My Project
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Modules
fs.c
Go to the documentation of this file.
1 #include <string.h>
2 #include <3ds.h>
3 
12 static Handle fsuHandle;
13 
14 // used to determine whether or not we should do FSUSER_Initialize on fsuHandle
15 Handle __get_handle_from_list(char* name);
16 
21 Result
22 fsInit(void)
23 {
24  Result ret;
25  if((ret=srvGetServiceHandle(&fsuHandle, "fs:USER"))!=0)return ret;
26  if(__get_handle_from_list("fs:USER")==0)ret=FSUSER_Initialize(NULL);
27  return ret;
28 }
29 
34 Result
35 fsExit(void)
36 {
37  return svcCloseHandle(fsuHandle);
38 }
39 
64 Result
66 {
67  if(!handle)
68  {
69  // don't run command if we got handle from the list
70  handle = &fsuHandle;
71  if(fsuHandle != 0 && __get_handle_from_list("fs:USER")!=0)
72  return 0;
73  }
74 
75  u32 *cmdbuf = getThreadCommandBuffer();
76 
77  cmdbuf[0] = 0x08010002;
78  cmdbuf[1] = 0x20;
79 
80  Result ret = 0;
81  if((ret = svcSendSyncRequest(*handle)))
82  return ret;
83 
84  return cmdbuf[1];
85 }
86 
129 Result
131  Handle *out,
132  FS_archive archive,
133  FS_path fileLowPath,
134  u32 openFlags,
135  u32 attributes)
136 {
137  if(!handle)
138  handle = &fsuHandle;
139 
140  u32 *cmdbuf = getThreadCommandBuffer();
141 
142  cmdbuf[0] = 0x080201C2;
143  cmdbuf[1] = 0;
144  cmdbuf[2] = archive.handleLow;
145  cmdbuf[3] = archive.handleHigh;
146  cmdbuf[4] = fileLowPath.type;
147  cmdbuf[5] = fileLowPath.size;
148  cmdbuf[6] = openFlags;
149  cmdbuf[7] = attributes;
150  cmdbuf[8] = (fileLowPath.size << 14) | 0x2;
151  cmdbuf[9] = (u32)fileLowPath.data;
152 
153  Result ret = 0;
154  if((ret = svcSendSyncRequest(*handle)))
155  return ret;
156 
157  if(out)
158  *out = cmdbuf[3];
159 
160  return cmdbuf[1];
161 }
162 
208 Result
210  Handle *out,
211  FS_archive archive,
212  FS_path fileLowPath,
213  u32 openFlags,
214  u32 attributes)
215 {
216  if(!handle)
217  handle = &fsuHandle;
218 
219  u32 *cmdbuf = getThreadCommandBuffer();
220 
221  cmdbuf[ 0] = 0x08030204;
222  cmdbuf[ 1] = 0;
223  cmdbuf[ 2] = archive.id;
224  cmdbuf[ 3] = archive.lowPath.type;
225  cmdbuf[ 4] = archive.lowPath.size;
226  cmdbuf[ 5] = fileLowPath.type;
227  cmdbuf[ 6] = fileLowPath.size;
228  cmdbuf[ 7] = openFlags;
229  cmdbuf[ 8] = attributes;
230  cmdbuf[ 9] = (archive.lowPath.size << 14) | 0x802;
231  cmdbuf[10] = (u32)archive.lowPath.data;
232  cmdbuf[11] = (fileLowPath.size << 14) | 0x2;
233  cmdbuf[12] = (u32)fileLowPath.data;
234 
235  Result ret = 0;
236  if((ret = svcSendSyncRequest(*handle)))
237  return ret;
238 
239  if(out)
240  *out = cmdbuf[3];
241 
242  return cmdbuf[1];
243 }
244 
275 Result
277  FS_archive archive,
278  FS_path fileLowPath)
279 {
280  if(!handle)
281  handle = &fsuHandle;
282 
283  u32 *cmdbuf = getThreadCommandBuffer();
284 
285  cmdbuf[0] = 0x08040142;
286  cmdbuf[1] = 0;
287  cmdbuf[2] = archive.handleLow;
288  cmdbuf[3] = archive.handleHigh;
289  cmdbuf[4] = fileLowPath.type;
290  cmdbuf[5] = fileLowPath.size;
291  cmdbuf[6] = (fileLowPath.size << 14) | 0x2;
292  cmdbuf[7] = (u32)fileLowPath.data;
293 
294  Result ret = 0;
295  if((ret = svcSendSyncRequest(*handle)))
296  return ret;
297 
298  return cmdbuf[1];
299 }
300 
339 Result
341  FS_archive srcArchive,
342  FS_path srcFileLowPath,
343  FS_archive destArchive,
344  FS_path destFileLowPath)
345 {
346  if(!handle)
347  handle = &fsuHandle;
348 
349  u32 *cmdbuf = getThreadCommandBuffer();
350 
351  cmdbuf[0] = 0x08050244;
352  cmdbuf[1] = 0;
353  cmdbuf[2] = srcArchive.handleLow;
354  cmdbuf[3] = srcArchive.handleHigh;
355  cmdbuf[4] = srcFileLowPath.type;
356  cmdbuf[5] = srcFileLowPath.size;
357  cmdbuf[6] = destArchive.handleLow;
358  cmdbuf[7] = destArchive.handleHigh;
359  cmdbuf[8] = destFileLowPath.type;
360  cmdbuf[9] = destFileLowPath.size;
361  cmdbuf[10] = (srcFileLowPath.size << 14) | 0x402;
362  cmdbuf[11] = (u32)srcFileLowPath.data;
363  cmdbuf[12] = (destFileLowPath.size << 14) | 0x802;
364  cmdbuf[13] = (u32)destFileLowPath.data;
365 
366  Result ret = 0;
367  if((ret = svcSendSyncRequest(*handle)))
368  return ret;
369 
370  return cmdbuf[1];
371 }
372 
403 Result
405  FS_archive archive,
406  FS_path dirLowPath)
407 {
408  if(!handle)
409  handle = &fsuHandle;
410 
411  u32 *cmdbuf = getThreadCommandBuffer();
412 
413  cmdbuf[0] = 0x08060142;
414  cmdbuf[1] = 0;
415  cmdbuf[2] = archive.handleLow;
416  cmdbuf[3] = archive.handleHigh;
417  cmdbuf[4] = dirLowPath.type;
418  cmdbuf[5] = dirLowPath.size;
419  cmdbuf[6] = (dirLowPath.size << 14) | 0x2;
420  cmdbuf[7] = (u32)dirLowPath.data;
421 
422  Result ret = 0;
423  if((ret = svcSendSyncRequest(*handle)))
424  return ret;
425 
426  return cmdbuf[1];
427 }
428 
429 /* stub */
430 Result
432 {
433  return -1;
434 }
435 
436 /* stub */
437 Result
439 {
440  return -1;
441 }
442 
474 Result
476  FS_archive archive,
477  FS_path dirLowPath)
478 {
479  if(!handle)
480  handle = &fsuHandle;
481 
482  u32 *cmdbuf = getThreadCommandBuffer();
483 
484  cmdbuf[0] = 0x08090182;
485  cmdbuf[1] = 0;
486  cmdbuf[2] = archive.handleLow;
487  cmdbuf[3] = archive.handleHigh;
488  cmdbuf[4] = dirLowPath.type;
489  cmdbuf[5] = dirLowPath.size;
490  cmdbuf[6] = 0;
491  cmdbuf[7] = (dirLowPath.size << 14) | 0x2;
492  cmdbuf[8] = (u32)dirLowPath.data;
493 
494  Result ret = 0;
495  if((ret = svcSendSyncRequest(*handle)))
496  return ret;
497 
498  return cmdbuf[1];
499 }
500 
539 Result
541  FS_archive srcArchive,
542  FS_path srcDirLowPath,
543  FS_archive destArchive,
544  FS_path destDirLowPath)
545 {
546  if(!handle)
547  handle = &fsuHandle;
548 
549  u32 *cmdbuf = getThreadCommandBuffer();
550 
551  cmdbuf[0] = 0x080A0244;
552  cmdbuf[1] = 0;
553  cmdbuf[2] = srcArchive.handleLow;
554  cmdbuf[3] = srcArchive.handleHigh;
555  cmdbuf[4] = srcDirLowPath.type;
556  cmdbuf[5] = srcDirLowPath.size;
557  cmdbuf[6] = destArchive.handleLow;
558  cmdbuf[7] = destArchive.handleHigh;
559  cmdbuf[8] = destDirLowPath.type;
560  cmdbuf[9] = destDirLowPath.size;
561  cmdbuf[10] = (srcDirLowPath.size << 14) | 0x402;
562  cmdbuf[11] = (u32)srcDirLowPath.data;
563  cmdbuf[12] = (destDirLowPath.size << 14) | 0x802;
564  cmdbuf[13] = (u32)destDirLowPath.data;
565 
566  Result ret = 0;
567  if((ret = svcSendSyncRequest(*handle)))
568  return ret;
569 
570  return cmdbuf[1];
571 }
572 
604 Result
606  Handle *out,
607  FS_archive archive,
608  FS_path dirLowPath)
609 {
610  if(!handle)
611  handle = &fsuHandle;
612 
613  u32 *cmdbuf = getThreadCommandBuffer();
614 
615  cmdbuf[0] = 0x080B0102;
616  cmdbuf[1] = archive.handleLow;
617  cmdbuf[2] = archive.handleHigh;
618  cmdbuf[3] = dirLowPath.type;
619  cmdbuf[4] = dirLowPath.size;
620  cmdbuf[5] = (dirLowPath.size << 14) | 0x2;
621  cmdbuf[6] = (u32)dirLowPath.data;
622 
623  Result ret = 0;
624  if((ret = svcSendSyncRequest(*handle)))
625  return ret;
626 
627  if(out)
628  *out = cmdbuf[3];
629 
630  return cmdbuf[1];
631 }
632 
662 Result
664  FS_archive *archive)
665 {
666  if(!archive)
667  return -2;
668 
669  if(!handle)
670  handle = &fsuHandle;
671 
672  u32 *cmdbuf = getThreadCommandBuffer();
673 
674  cmdbuf[0] = 0x080C00C2;
675  cmdbuf[1] = archive->id;
676  cmdbuf[2] = archive->lowPath.type;
677  cmdbuf[3] = archive->lowPath.size;
678  cmdbuf[4] = (archive->lowPath.size << 14) | 0x2;
679  cmdbuf[5] = (u32)archive->lowPath.data;
680 
681  Result ret = 0;
682  if((ret = svcSendSyncRequest(*handle)))
683  return ret;
684 
685  archive->handleLow = cmdbuf[2];
686  archive->handleHigh = cmdbuf[3];
687 
688  return cmdbuf[1];
689 }
690 
691 
716 Result
718  FS_archive *archive)
719 {
720  if(!archive)
721  return -2;
722 
723  if(!handle)
724  handle = &fsuHandle;
725 
726  u32 *cmdbuf = getThreadCommandBuffer();
727 
728  cmdbuf[0] = 0x080E0080;
729  cmdbuf[1] = archive->handleLow;
730  cmdbuf[2] = archive->handleHigh;
731 
732  Result ret = 0;
733  if((ret = svcSendSyncRequest(*handle)))
734  return ret;
735 
736  return cmdbuf[1];
737 }
738 
768 Result
770  u32 *sectorSize,
771  u32 *clusterSize,
772  u32 *numClusters,
773  u32 *freeClusters)
774 {
775  if(!handle)
776  handle = &fsuHandle;
777 
778  u32 *cmdbuf = getThreadCommandBuffer();
779 
780  cmdbuf[0] = 0x08140000;
781 
782  Result ret = 0;
783  if((ret = svcSendSyncRequest(*handle)))
784  return ret;
785 
786  if(sectorSize)
787  *sectorSize = cmdbuf[2];
788 
789  if(clusterSize)
790  *clusterSize = cmdbuf[3];
791 
792  if(numClusters)
793  *numClusters = cmdbuf[4];
794 
795  if(freeClusters)
796  *freeClusters = cmdbuf[5];
797 
798  return cmdbuf[1];
799 }
800 
824 Result
826  u32 *detected)
827 {
828  if(!handle)
829  handle = &fsuHandle;
830 
831  u32 *cmdbuf = getThreadCommandBuffer();
832 
833  cmdbuf[0] = 0x08170000;
834 
835  Result ret = 0;
836  if((ret = svcSendSyncRequest(*handle)))
837  return ret;
838 
839  if(detected)
840  *detected = cmdbuf[2];
841 
842  return cmdbuf[1];
843 }
844 
868 Result
870  u32 *writable)
871 {
872  if(!handle)
873  handle = &fsuHandle;
874 
875  u32 *cmdbuf = getThreadCommandBuffer();
876 
877  cmdbuf[0] = 0x08180000;
878 
879  Result ret = 0;
880  if((ret = svcSendSyncRequest(*handle)))
881  return ret;
882 
883  if(writable)
884  *writable = cmdbuf[2];
885 
886  return cmdbuf[1];
887 }
888 
910 Result
912 {
913  u32* cmdbuf = getThreadCommandBuffer();
914 
915  cmdbuf[0] = 0x08080000;
916 
917  Result ret = 0;
918  if((ret = svcSendSyncRequest(handle)))
919  return ret;
920 
921  ret = cmdbuf[1];
922  if(!ret)ret = svcCloseHandle(handle);
923 
924  return ret;
925 }
926 
958 Result
960  u32 *bytesRead,
961  u64 offset,
962  void *buffer,
963  u32 size)
964 {
965  u32 *cmdbuf = getThreadCommandBuffer();
966 
967  cmdbuf[0] = 0x080200C2;
968  cmdbuf[1] = (u32)offset;
969  cmdbuf[2] = (u32)(offset >> 32);
970  cmdbuf[3] = size;
971  cmdbuf[4] = (size << 4) | 0xC;
972  cmdbuf[5] = (u32)buffer;
973 
974  Result ret = 0;
975  if((ret = svcSendSyncRequest(handle)))
976  return ret;
977 
978  if(bytesRead)
979  *bytesRead = cmdbuf[2];
980 
981  return cmdbuf[1];
982 }
983 
1025 Result
1027  u32 *bytesWritten,
1028  u64 offset,
1029  const void *buffer,
1030  u32 size,
1031  u32 flushFlags)
1032 {
1033  u32 *cmdbuf = getThreadCommandBuffer();
1034 
1035  cmdbuf[0] = 0x08030102;
1036  cmdbuf[1] = (u32)offset;
1037  cmdbuf[2] = (u32)(offset >> 32);
1038  cmdbuf[3] = size;
1039  cmdbuf[4] = flushFlags;
1040  cmdbuf[5] = (size << 4) | 0xA;
1041  cmdbuf[6] = (u32)buffer;
1042 
1043  Result ret = 0;
1044  if((ret = svcSendSyncRequest(handle)))
1045  return ret;
1046 
1047  if(bytesWritten)
1048  *bytesWritten = cmdbuf[2];
1049 
1050  return cmdbuf[1];
1051 }
1052 
1077 Result
1079  u64 *size)
1080 {
1081  u32 *cmdbuf = getThreadCommandBuffer();
1082 
1083  cmdbuf[0] = 0x08040000;
1084 
1085  Result ret = 0;
1086  if((ret = svcSendSyncRequest(handle)))
1087  return ret;
1088 
1089  if(size)
1090  *size = (u64)cmdbuf[2] | ((u64)cmdbuf[3] << 32);
1091 
1092  return cmdbuf[1];
1093 }
1094 
1119 Result
1121  u64 size)
1122 {
1123  u32 *cmdbuf = getThreadCommandBuffer();
1124 
1125  cmdbuf[0] = 0x08050080;
1126  cmdbuf[1] = (u32)size;
1127  cmdbuf[2] = (u32)(size >> 32);
1128 
1129  Result ret = 0;
1130  if((ret = svcSendSyncRequest(handle)))
1131  return ret;
1132 
1133 
1134  return cmdbuf[1];
1135 }
1136 
1160 Result
1162  u32 *attributes)
1163 {
1164  u32 *cmdbuf = getThreadCommandBuffer();
1165 
1166  cmdbuf[0] = 0x08060000;
1167 
1168  Result ret = 0;
1169  if((ret = svcSendSyncRequest(handle)))
1170  return ret;
1171 
1172  if(attributes)
1173  *attributes = cmdbuf[2];
1174 
1175  return cmdbuf[1];
1176 }
1177 
1201 Result
1203  u32 attributes)
1204 {
1205  u32 *cmdbuf = getThreadCommandBuffer();
1206 
1207  cmdbuf[0] = 0x08070040;
1208  cmdbuf[1] = attributes;
1209 
1210  Result ret = 0;
1211  if((ret = svcSendSyncRequest(handle)))
1212  return ret;
1213 
1214  return cmdbuf[1];
1215 }
1216 
1238 Result
1240 {
1241  u32 *cmdbuf = getThreadCommandBuffer();
1242 
1243  cmdbuf[0] = 0x08090000;
1244 
1245  Result ret = 0;
1246  if((ret = svcSendSyncRequest(handle)))
1247  return ret;
1248 
1249  return cmdbuf[1];
1250 }
1251 
1280 Result
1282  u32 *entriesRead,
1283  u32 entryCount,
1284  FS_dirent *buffer)
1285 {
1286  u32 *cmdbuf = getThreadCommandBuffer();
1287 
1288  cmdbuf[0] = 0x08010042;
1289  cmdbuf[1] = entryCount;
1290  cmdbuf[2] = ((entryCount*0x228) << 4) | 0xC;
1291  cmdbuf[3] = (u32)buffer;
1292 
1293  Result ret = 0;
1294  if((ret = svcSendSyncRequest(handle)))
1295  return ret;
1296 
1297  if(entriesRead)
1298  *entriesRead = cmdbuf[2];
1299 
1300  return cmdbuf[1];
1301 }
1302 
1324 Result
1326 {
1327  u32 *cmdbuf = getThreadCommandBuffer();
1328 
1329  cmdbuf[0] = 0x08020000;
1330 
1331  Result ret = 0;
1332  if((ret = svcSendSyncRequest(handle)))
1333  return ret;
1334  ret = cmdbuf[1];
1335  if(!ret)ret = svcCloseHandle(handle);
1336  return ret;
1337 }
Definition: fs.h:105
s32 Result
Definition: types.h:42
s32 svcCloseHandle(Handle handle)
Result FSUSER_DeleteDirectory(Handle *handle, FS_archive archive, FS_path dirLowPath)
Definition: fs.c:404
Result srvGetServiceHandle(Handle *out, const char *name)
Definition: srv.c:109
Result FSUSER_OpenDirectory(Handle *handle, Handle *out, FS_archive archive, FS_path dirLowPath)
Definition: fs.c:605
Result FSUSER_IsSdmcWritable(Handle *handle, u32 *writable)
Definition: fs.c:869
FS_pathType type
FS path type.
Definition: fs.h:90
Result FSDIR_Close(Handle handle)
Definition: fs.c:1325
Result FSUSER_OpenArchive(Handle *handle, FS_archive *archive)
Definition: fs.c:663
Handle __get_handle_from_list(char *name)
Result FSFILE_Close(Handle handle)
Definition: fs.c:911
u32 Handle
Definition: types.h:41
Result FSFILE_Flush(Handle handle)
Definition: fs.c:1239
u32 * getThreadCommandBuffer(void)
uint64_t u64
Definition: types.h:24
Result FSUSER_CloseArchive(Handle *handle, FS_archive *archive)
Definition: fs.c:717
Result FSUSER_OpenFileDirectly(Handle *handle, Handle *out, FS_archive archive, FS_path fileLowPath, u32 openFlags, u32 attributes)
Definition: fs.c:209
u32 id
Archive ID.
Definition: fs.h:98
Result FSUSER_CreateFile(void)
Definition: fs.c:438
Result FSUSER_GetSdmcArchiveResource(Handle *handle, u32 *sectorSize, u32 *clusterSize, u32 *numClusters, u32 *freeClusters)
Definition: fs.c:769
Result FSFILE_GetAttributes(Handle handle, u32 *attributes)
Definition: fs.c:1161
uint32_t u32
Definition: types.h:23
Result fsInit(void)
Definition: fs.c:22
Result FSFILE_GetSize(Handle handle, u64 *size)
Definition: fs.c:1078
Result FSUSER_Initialize(Handle *handle)
Definition: fs.c:65
Result FSUSER_CreateDirectory(Handle *handle, FS_archive archive, FS_path dirLowPath)
Definition: fs.c:475
Result FSUSER_IsSdmcDetected(Handle *handle, u32 *detected)
Definition: fs.c:825
FS_path lowPath
FS path.
Definition: fs.h:99
Result FSFILE_Write(Handle handle, u32 *bytesWritten, u64 offset, const void *buffer, u32 size, u32 flushFlags)
Definition: fs.c:1026
Result fsExit(void)
Definition: fs.c:35
const u8 * data
Pointer to FS path data.
Definition: fs.h:92
Definition: fs.h:96
Definition: fs.h:88
Handle handleLow
High word of handle.
Definition: fs.h:100
Result FSUSER_DeleteFile(Handle *handle, FS_archive archive, FS_path fileLowPath)
Definition: fs.c:276
Result FSDIR_Read(Handle handle, u32 *entriesRead, u32 entryCount, FS_dirent *buffer)
Definition: fs.c:1281
Handle handleHigh
Low word of handle.
Definition: fs.h:101
Result FSUSER_RenameFile(Handle *handle, FS_archive srcArchive, FS_path srcFileLowPath, FS_archive destArchive, FS_path destFileLowPath)
Definition: fs.c:340
Result FSFILE_SetSize(Handle handle, u64 size)
Definition: fs.c:1120
Result FSUSER_OpenFile(Handle *handle, Handle *out, FS_archive archive, FS_path fileLowPath, u32 openFlags, u32 attributes)
Definition: fs.c:130
s32 svcSendSyncRequest(Handle session)
Result FSFILE_SetAttributes(Handle handle, u32 attributes)
Definition: fs.c:1202
Result FSUSER_RenameDirectory(Handle *handle, FS_archive srcArchive, FS_path srcDirLowPath, FS_archive destArchive, FS_path destDirLowPath)
Definition: fs.c:540
u32 size
FS path size.
Definition: fs.h:91
Result FSUSER_DeleteDirectoryRecursively(void)
Definition: fs.c:431
Result FSFILE_Read(Handle handle, u32 *bytesRead, u64 offset, void *buffer, u32 size)
Definition: fs.c:959