Zeal 瞬间文件分割工具完整源码

 

  
  
  
  
  1. /************************************************************************/ 
  2. /* Zeal 0.11 In-place file splitter  
  3. /* By Roger 2008.11.29 http://rogerfd.cn 
  4. /* Change log:  
  5. /* 2009.2.12 v0.11 fixes a bug when open file with . in dir 
  6. /************************************************************************/ 
  7.  
  8. #include <stdio.h> 
  9. #include <stdlib.h> 
  10. #include <io.h> 
  11. #include <windows.h> 
  12. #include <Shlobj.h> 
  13.  
  14. #pragma pack(push, 1) 
  15.  
  16. typedef struct _fat32_boot_sector 
  17. BYTE u1[11]; 
  18. WORD bytes_per_sector; 
  19. BYTE sectors_per_cluster; 
  20. WORD reserved_sectors_count; 
  21. BYTE fats_count; 
  22. BYTE u2[11]; 
  23. DWORD hidden_sectors; 
  24. DWORD total_sectors_2; 
  25. DWORD sectors_per_fat32; 
  26. BYTE u3[4]; 
  27. DWORD rootdir_cluster; 
  28. BYTE u4[34]; 
  29. char type[8]; 
  30. BYTE u5[420]; 
  31. WORD end_flag; 
  32. }fat32_boot_sector; 
  33.  
  34. typedef struct _dir_item 
  35. char name[8]; 
  36. char ext[3]; 
  37. BYTE attr; 
  38. BYTE reserved; 
  39. BYTE create_time_ms; 
  40. WORD create_time; 
  41. WORD create_date; 
  42. WORD last_access_time_ms; 
  43. WORD first_cluster_high; 
  44. WORD last_access_time; 
  45. WORD last_access_date; 
  46. WORD first_cluster_low; 
  47. DWORD size; 
  48. }dir_item; 
  49.  
  50. #pragma pack(pop) 
  51.  
  52. #define MAX_BLOCK 127 
  53.  
  54. class zeal 
  55.  
  56. public
  57.  
  58. zeal ()  
  59. m_bDebug = false
  60. m_bOpen = false
  61. m_arryFatCache = NULL; 
  62. }; 
  63. ~zeal ()  
  64. }; 
  65. void set_debug (bool debug)  
  66. m_bDebug = debug; 
  67. int cut (const char* szFile, unsigned int count); 
  68. int restore (const char* szFile); 
  69.  
  70. private
  71.  
  72. int open (char vol); 
  73. void close (); 
  74. DWORD get_fat (DWORD fat_index); 
  75. int set_fat (DWORD fat_index, DWORD fat_value); 
  76. int create_empty_file (const char* szFile); 
  77. int find_item (DWORD dir_cluster, const char* szShortName, OUT DWORD& first_cluster); 
  78. int set_item (DWORD dir_cluster, const char* szShortName, DWORD size, DWORD firstcluster); 
  79. DWORD get_last_fat (DWORD fat_index); 
  80. void msg_debug (const char* msg, ...); 
  81. void msg_error (const char* msg, ...); 
  82.  
  83. int m_vol; 
  84. bool m_bDebug; 
  85. bool m_bOpen; 
  86. HANDLE m_hVol; 
  87. DWORD m_OffsetFat1; 
  88. DWORD m_OffsetFat2; 
  89. DWORD m_OffsetCluster0; 
  90. DWORD m_OffsetRootdir; 
  91. DWORD m_ClusterSize; 
  92. PDWORD m_arryFatCache; 
  93. fat32_boot_sector m_BootSector; 
  94. }; 
  95.  
  96. void zeal::msg_debug (const char* msg, ...) 
  97. if (!m_bDebug)  
  98. return
  99. va_list arg; 
  100. va_start (arg, msg);  
  101. vprintf (msg, arg); 
  102. va_end (arg); 
  103.  
  104. void zeal::msg_error (const char* msg, ...) 
  105. va_list arg; 
  106. va_start (arg, msg);  
  107. vprintf (msg, arg); 
  108. va_end (arg); 
  109.  
  110. int zeal::create_empty_file (const char* szFile) 
  111. msg_debug ("creating %s ... \n", szFile); 
  112. HANDLE h = CreateFile (szFile, 0, 0, 0, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, 0); 
  113. if (h == INVALID_HANDLE_VALUE) 
  114. return -1; 
  115. CloseHandle (h); 
  116. return 0; 
  117.  
  118. void strncpy_no_null (char* to, const char* from, int maxchar) 
  119. for (int i = 0; i < maxchar; ++i) 
  120. if (from[i] == 0) 
  121. break
  122. to [i] = from [i]; 
  123.  
  124. void merge_short_name (const char* name, const char* ext, char* shortname) 
  125. memset (shortname, ' ', 11); 
  126. strncpy_no_null (shortname, name, 8); 
  127. strncpy_no_null (shortname + 8, ext+1, 3); 
  128.  
  129. DWORD get_file_size (const char* szFile) 
  130. HANDLE hFile = CreateFile (szFile, 0,  
  131. FILE_SHARE_WRITE|FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); 
  132. if (hFile == INVALID_HANDLE_VALUE) 
  133. return 0; 
  134. DWORD dwLSize; 
  135. dwLSize = GetFileSize (hFile, NULL); 
  136. CloseHandle (hFile); 
  137. return dwLSize; 
  138.  
  139. DWORD zeal::get_fat (DWORD index) 
  140. DWORD off = (m_OffsetFat1 + 4*index) & ~0x1FF; 
  141. if (!m_bOpen) 
  142. goto failed; 
  143.  
  144. if (index * m_BootSector.sectors_per_cluster + m_OffsetCluster0/512 > m_BootSector.total_sectors_2) 
  145. msg_error ("get_fat() error: invalid param!\n"); 
  146. goto failed; 
  147.  
  148. if (m_arryFatCache[index] != 1) 
  149. return m_arryFatCache[index] & 0x0FFFFFFF; 
  150.  
  151. if (off != SetFilePointer (m_hVol, off, 0, FILE_BEGIN)) 
  152. msg_error ("SetFilePointer failed!\n"); 
  153. goto failed; 
  154.  
  155. DWORD read, fat; 
  156. DWORD buf[128]; 
  157. if (!ReadFile (m_hVol, (PBYTE)buf, 512, &read, NULL) || read != 512) 
  158. msg_error ("ReadFile failed!\n"); 
  159. goto failed; 
  160. fat = buf [(m_OffsetFat1/4 + index) % 128]; 
  161. memcpy ((PBYTE)m_arryFatCache + 4*index - ((m_OffsetFat1 + 4*index) & 0x1FF), buf, 512); 
  162. return fat & 0x0FFFFFFF; 
  163.  
  164. failed: 
  165. return ~0; 
  166.  
  167. DWORD zeal::get_last_fat (DWORD fat_index) 
  168. DWORD cluster = fat_index; 
  169. DWORD next_cluster; 
  170. while (TRUE) 
  171. next_cluster = get_fat (cluster); 
  172. if (next_cluster >= 0xFFFFFF8 && next_cluster <=0xFFFFFFF) 
  173. return cluster; 
  174. cluster = next_cluster; 
  175.  
  176. int zeal::set_fat (DWORD fat_index, DWORD fat_value) 
  177. DWORD off = (m_OffsetFat1 + 4*fat_index) & ~0x1FF; 
  178.  
  179. if (!m_bOpen) 
  180. goto failed; 
  181.  
  182. if (fat_index * m_BootSector.sectors_per_cluster + m_OffsetCluster0/512 > m_BootSector.total_sectors_2) 
  183. msg_error ("get_fat() error: invalid param!\n"); 
  184. goto failed; 
  185.  
  186. if (off != SetFilePointer (m_hVol, off, 0, FILE_BEGIN)) 
  187. msg_error ("SetFilePointer failed!\n"); 
  188. goto failed; 
  189.  
  190. DWORD read; 
  191. DWORD buf[128]; 
  192. if (!ReadFile (m_hVol, (PBYTE)buf, 512, &read, NULL) || read != 512) 
  193. msg_error ("ReadFile failed!\n"); 
  194. goto failed; 
  195.  
  196. buf [(m_OffsetFat1/4 + fat_index) % 128] = fat_value; 
  197.  
  198. if (off != SetFilePointer (m_hVol, off, 0, FILE_BEGIN)) 
  199. goto failed; 
  200.  
  201. if (!WriteFile (m_hVol, (PBYTE)buf, 512, &read, NULL) || read != 512) 
  202. msg_error ("WriteFile failed!\n"); 
  203. goto failed; 
  204.  
  205. off = (m_OffsetFat2 + 4*fat_index) & ~0x1FF; 
  206. if (off != SetFilePointer (m_hVol, off, 0, FILE_BEGIN)) 
  207. msg_error ("SetFilePointer failed!\n"); 
  208. goto failed; 
  209.  
  210. if (!WriteFile (m_hVol, (PBYTE)buf, 512, &read, NULL) || read != 512) 
  211. msg_error ("WriteFile failed!\n"); 
  212. goto failed; 
  213.  
  214. return 0; 
  215.  
  216. failed: 
  217. return -1; 
  218.  
  219. int zeal::set_item (DWORD dir_cluster, const char* szShortName, DWORD size, DWORD firstcluster) 
  220. if (!m_bOpen) 
  221. {  
  222. return -1; 
  223.  
  224. msg_debug ("try to find %s in 0x%x cluster\n", szShortName, dir_cluster); 
  225.  
  226. DWORD cluster = dir_cluster; 
  227. LARGE_INTEGER toMove, moved; 
  228. PBYTE buf = new BYTE [m_ClusterSize]; 
  229. for (;;) 
  230. toMove.QuadPart = cluster * m_ClusterSize + m_OffsetCluster0; 
  231. if (!SetFilePointerEx (m_hVol, toMove, &moved, FILE_BEGIN)) 
  232. msg_error ("SetFilePointerEx failed!\n"); 
  233. goto failed; 
  234.  
  235. DWORD read; 
  236. if (!ReadFile (m_hVol, buf, m_ClusterSize, &read, NULL) || read != m_ClusterSize) 
  237. msg_error ("ReadFile failed!\n"); 
  238. goto failed; 
  239. dir_item *pItem = (dir_item*) buf; 
  240. for (DWORD i = 0; i < m_ClusterSize/32; ++i, ++pItem) 
  241. msg_debug ("%d name: %0.11s\n", i, pItem->name); 
  242. if (pItem->name[0] == 0) 
  243. msg_error ("file %s not found!\n", szShortName); 
  244. goto failed; 
  245. if (!strnicmp (pItem->name, szShortName, 11)) 
  246. pItem->size = size; 
  247. pItem->first_cluster_low = WORD(firstcluster & 0xFFFF); 
  248. pItem->first_cluster_high = WORD(firstcluster >> 16); 
  249. if (!SetFilePointerEx (m_hVol, toMove, &moved, FILE_BEGIN)) 
  250. msg_error ("SetFilePointerEx failed!\n"); 
  251. goto failed; 
  252. DWORD writen; 
  253. if (!WriteFile (m_hVol, buf, m_ClusterSize, &writen, NULL) || writen != m_ClusterSize) 
  254. msg_error ("WriteFile failed!\n"); 
  255. goto failed; 
  256. return 0; 
  257.  
  258. cluster = get_fat (cluster); 
  259. if ((0xFFFFFF8 & cluster) == 0xFFFFFF8) 
  260. msg_error ("file %s not found!\n", szShortName); 
  261. goto failed; 
  262. msg_debug ("try next cluster %X... \n", cluster); 
  263.  
  264. failed: 
  265. delete[] buf; 
  266. return -1; 
  267.  
  268. int zeal::find_item (DWORD dir_cluster, const char* szShortName, OUT DWORD& first_cluster) 
  269. if (!m_bOpen) 
  270. return -1; 
  271.  
  272. msg_debug ("try to find %s in 0x%x cluster\n", szShortName, dir_cluster); 
  273. DWORD cluster = dir_cluster; 
  274. LARGE_INTEGER toMove, moved; 
  275. PBYTE buf = new BYTE [m_ClusterSize]; 
  276. char name[11]; 
  277. memset (name, ' ', 11); 
  278. strncpy_no_null (name, szShortName, 11); 
  279. for (;;) 
  280. toMove.QuadPart = cluster * m_ClusterSize + m_OffsetCluster0; 
  281. if (!SetFilePointerEx (m_hVol, toMove, &moved, FILE_BEGIN)) 
  282. msg_error ("SetFilePointerEx failed!\n"); 
  283. goto failed; 
  284.  
  285. DWORD read; 
  286. if (!ReadFile (m_hVol, buf, m_ClusterSize, &read, NULL) || read != m_ClusterSize) 
  287. msg_error ("ReadFile failed!\n"); 
  288. goto failed; 
  289. dir_item *pItem = (dir_item*) buf; 
  290. for (DWORD i = 0; i < m_ClusterSize/32; ++i, ++pItem) 
  291. msg_debug ("%d name: %0.11s\n", i, pItem->name); 
  292. if (pItem->name[0] == 0) 
  293. msg_error ("file %s not found!\n", szShortName); 
  294. goto failed; 
  295. if (!strnicmp (pItem->name, name, 11)) 
  296. {  
  297. first_cluster = (pItem->first_cluster_high << 16) + pItem->first_cluster_low; 
  298. msg_debug ("%0.11s found at 0x%x cluster!\n", name, first_cluster); 
  299. delete[] buf; 
  300. return 0; 
  301. cluster = get_fat (cluster); 
  302. if (cluster < 2 || cluster > 0xFFFFFEF) 
  303. msg_error ("file %s not found!\n", szShortName); 
  304. goto failed; 
  305.  
  306. failed: 
  307. delete[] buf; 
  308. return -1; 
  309.  
  310. int zeal::restore (const char* szFile) 
  311. char drv[4], shortname[12], path[MAX_PATH], filename[MAX_PATH], ext[MAX_PATH]; 
  312. char oripath[MAX_PATH] = {0}, shortpath[MAX_PATH], newpath[MAX_PATH]; 
  313. DWORD count, i, ret; 
  314. char *p, *subdir; 
  315. DWORD firstclusters[MAX_BLOCK+1], lastclusters[MAX_BLOCK+1]; 
  316. DWORD cluster = 2, nextcluster, dirCluster, filesize = 0; 
  317. DWORD startTime = GetTickCount (); 
  318.  
  319. _splitpath (szFile, drv, path, filename, ext); 
  320. if (stricmp (ext, ".zeal")) 
  321. msg_error ("Not generated by zeal!\n"); 
  322. goto failed; 
  323.  
  324. p = strstr (filename, ".part"); 
  325. if (!p) 
  326. msg_error ("Not generated by zeal!\n"); 
  327. goto failed; 
  328.  
  329. if (sscanf (p + 5, "%*d-%d", &count) != 1) 
  330. msg_error ("Not generated by zeal!\n"); 
  331. goto failed; 
  332.  
  333. memcpy (oripath, szFile, strstr (szFile, ".part") - szFile); 
  334. msg_debug ("ori file path: %s\n", oripath); 
  335. if (!_access (oripath, 0)) 
  336. msg_error ("%s already exists!\n", oripath); 
  337. goto failed; 
  338.  
  339. for (i = 1; i <= count; ++i) 
  340. sprintf (newpath, "%s.part%d-%d.zeal", oripath, i, count); 
  341. ret = get_file_size (newpath); 
  342. if (ret == 0) 
  343. msg_error ("%s missing!\n", newpath); 
  344. goto failed; 
  345. filesize += ret; 
  346.  
  347. if (open (drv[0])) 
  348. msg_error ("failed to open %s!\n", drv); 
  349. goto failed; 
  350.  
  351. // check size a again, to avoid this, make block size align to 64KB 
  352. for (i = 1; i < count; ++i) 
  353. sprintf (newpath, "%s.part%d-%d.zeal", oripath, i, count); 
  354. ret = get_file_size (newpath); 
  355. if (ret & (m_ClusterSize-1)) 
  356. msg_error ("file size alignment error!\n"); 
  357. goto failed; 
  358.  
  359. sprintf (newpath, "%s.part%d-%d.zeal", oripath, 1, count); 
  360. if(!GetShortPathName(newpath, shortpath, MAX_PATH)) 
  361. msg_error ("GetShortPathName (%s) failed!\n", newpath); 
  362. goto failed; 
  363. _splitpath (shortpath, drv, path, filename, ext); 
  364. subdir = strtok (path, "\\"); 
  365. while (subdir != NULL) 
  366. _splitpath (subdir, NULL, NULL, filename, ext); 
  367. merge_short_name (filename, ext, shortname); 
  368. if (find_item (cluster, shortname, nextcluster)) 
  369. msg_error ("find_item failed!\n"); 
  370. goto failed; 
  371. cluster = nextcluster; 
  372. subdir = strtok (NULL, "\\"); 
  373.  
  374. dirCluster = cluster; 
  375.  
  376. for (i = 1; i <= count; ++i) 
  377. sprintf (newpath, "%s.part%d-%d.zeal", oripath, i, count); 
  378. if(!GetShortPathName(newpath, shortpath, MAX_PATH)) 
  379. msg_error ("GetShortPathName (%s) failed!\n", newpath); 
  380. goto failed; 
  381.  
  382. _splitpath (shortpath, drv, path, filename, ext); 
  383. merge_short_name (filename, ext, shortname); 
  384. if (find_item (dirCluster, shortname, cluster)) 
  385. msg_error ("find_item failed!\n"); 
  386. goto failed; 
  387. if (i == 1) 
  388. if (set_item (dirCluster, shortname, filesize, cluster)) 
  389. msg_error ("set_item failed!\n"); 
  390. goto failed; 
  391. else 
  392. if (set_item (dirCluster, shortname, 0, 0)) 
  393. msg_error ("set_item failed!\n"); 
  394. goto failed; 
  395. firstclusters[i] = cluster; 
  396. lastclusters [i] = get_last_fat (cluster); 
  397.  
  398. for (i = 1; i < count; ++i) 
  399. if (set_fat (lastclusters[i], firstclusters[i+1])) 
  400. msg_error ("set_item failed!\n"); 
  401. goto failed; 
  402.  
  403. close (); 
  404.  
  405. for (i = 1; i <= count; ++i) 
  406. sprintf (newpath, "%s.part%d-%d.zeal", oripath, i, count); 
  407. if (i == 1) 
  408. if (rename (newpath, oripath)) 
  409. msg_error ("rename %s failed!\n", newpath); 
  410. goto failed; 
  411. else 
  412. if (remove (newpath)) 
  413. msg_error ("remove %s failed!\n", newpath); 
  414. goto failed; 
  415. SHChangeNotify (SHCNE_ALLEVENTS, 0, 0, 0);  
  416. printf ("Done! %d ms used\n", GetTickCount () - startTime); 
  417. return 0; 
  418.  
  419. failed: 
  420.  
  421. SHChangeNotify (SHCNE_ALLEVENTS, 0, 0, 0);  
  422. close (); 
  423. return -1;  
  424.  
  425.  
  426. int zeal::cut (const char* szFile, unsigned int count) 
  427. char drv[4], path[MAX_PATH], filename[MAX_PATH], ext[MAX_PATH]; 
  428. char shortpath[MAX_PATH], newpath[MAX_PATH]; 
  429. char shortname[12] = {0}; 
  430. DWORD nSize, nCluster, nLastCluster, nLastSize, dirCluster, i, j; 
  431. DWORD size = get_file_size (szFile); 
  432. DWORD firstclusters[MAX_BLOCK+1], lastclusters[MAX_BLOCK+1]; 
  433. char* subdir; 
  434. DWORD cluster = 2, nextcluster; 
  435. DWORD startTime = GetTickCount (); 
  436. bool files_created = false
  437.  
  438. if (count < 2) 
  439. msg_error ("Nothing to do ?\n"); 
  440. goto failed; 
  441.  
  442. if (count > MAX_BLOCK) 
  443. msg_error ("Too many blocks! Max %d\n", MAX_BLOCK); 
  444. goto failed; 
  445.  
  446. if(!GetShortPathName(szFile, shortpath, MAX_PATH)) 
  447. msg_error ("GetShortPathName (%s) failed!\n", szFile); 
  448. goto failed; 
  449.  
  450. _splitpath (shortpath, drv, path, filename, ext); 
  451.  
  452. // check if files already exists  
  453. for (i = 1; i <= count; ++i) 
  454. sprintf (newpath, "%s.part%d-%d.zeal", szFile, i, count); 
  455. if (!_access (newpath, 0)) 
  456. msg_error ("%s already exists!\n", newpath); 
  457. goto failed; 
  458. if (i!=1 && create_empty_file (newpath)) 
  459. msg_error ("Failed to create %s!\n", newpath); 
  460. goto failed; 
  461.  
  462. files_created = true
  463.  
  464. if (open (drv[0])) 
  465. msg_error ("failed to open %s!\n", drv); 
  466. goto failed; 
  467.  
  468. if (size < m_ClusterSize * count) 
  469. msg_error ("Block size < %d, exit!\n", m_ClusterSize); 
  470. goto failed; 
  471.  
  472. // size per block, down align to m_ClusterSize 
  473. nSize = (size / count) & ~(m_ClusterSize -1); 
  474. // clusters per block 
  475. nCluster = nSize / m_ClusterSize; 
  476. // size of last block 
  477. nLastSize = size - (count-1)*nSize; 
  478. // clusters of last block 
  479. nLastCluster = (nLastSize + m_ClusterSize - 1) / m_ClusterSize; 
  480.  
  481. subdir = strtok (path, "\\"); 
  482. while (subdir != NULL) 
  483. _splitpath (subdir, NULL, NULL, filename, ext); 
  484. merge_short_name (filename, ext, shortname); 
  485. if (find_item (cluster, shortname, nextcluster)) 
  486. msg_error ("find_item failed!\n"); 
  487. goto failed; 
  488. cluster = nextcluster; 
  489. subdir = strtok (NULL, "\\"); 
  490.  
  491. dirCluster = cluster; 
  492.  
  493. _splitpath (shortpath, drv, path, filename, ext); 
  494. merge_short_name (filename, ext, shortname); 
  495. if (find_item (dirCluster, shortname, nextcluster)) 
  496. msg_error ("find_item failed!\n"); 
  497. goto failed; 
  498.  
  499. // now nextcluster is the first content of the file 
  500. firstclusters[1] = nextcluster; 
  501. cluster = nextcluster; 
  502. for (i = 2; i <= count; ++i) 
  503. for (j = 0; j < nCluster; ++j) 
  504. if (j == nCluster - 1) 
  505. lastclusters[i-1] = cluster; 
  506. cluster = get_fat (cluster); 
  507. if (cluster < 0x2 || cluster > 0xFFFFFEF) 
  508. msg_error ("Error parsing fat!\n"); 
  509. goto failed; 
  510. firstclusters[i] = cluster; 
  511.  
  512. // set the others 
  513. for (i = 2; i < count; ++i) 
  514. sprintf (newpath, "%s.part%d-%d.zeal", szFile, i, count); 
  515. if(!GetShortPathName(newpath, shortpath, MAX_PATH)) 
  516. printf ("GetShortPathName (%s) failed!\n", newpath); 
  517. goto failed; 
  518. _splitpath (shortpath, drv, path, filename, ext); 
  519. merge_short_name (filename, ext, shortname); 
  520. if (set_item (dirCluster, shortname, nSize, firstclusters[i])) 
  521. msg_error ("set_item failed!\n"); 
  522. goto failed; 
  523. if (set_fat (lastclusters[i], 0x0FFFFFFF)) 
  524. msg_error ("set_fat failed!\n"); 
  525. goto failed; 
  526.  
  527. // set the last one 
  528. sprintf (newpath, "%s.part%d-%d.zeal", szFile, i, count); 
  529. if(!GetShortPathName(newpath, shortpath, MAX_PATH)) 
  530. msg_error ("GetShortPathName (%s) failed!\n", newpath); 
  531. goto failed; 
  532. _splitpath (shortpath, drv, path, filename, ext); 
  533. merge_short_name (filename, ext, shortname); 
  534. if (set_item (dirCluster, shortname, nLastSize, firstclusters[count])) 
  535. msg_error ("set_item failed!\n"); 
  536. goto failed; 
  537.  
  538. // set the first part  
  539. if(!GetShortPathName(szFile, shortpath, MAX_PATH)) 
  540. msg_error ("GetShortPathName (%s) failed!\n", newpath); 
  541. goto failed; 
  542. _splitpath (shortpath, drv, path, filename, ext); 
  543. merge_short_name (filename, ext, shortname); 
  544. if (set_item (dirCluster, shortname, nSize, firstclusters[1])) 
  545. msg_error ("set_item failed!\n"); 
  546. goto failed; 
  547. if (set_fat (lastclusters[1], 0x0FFFFFFF)) 
  548. msg_error ("set_fat failed!\n"); 
  549. goto failed; 
  550.  
  551. close (); 
  552.  
  553. sprintf (newpath, "%s.part%d-%d.zeal", szFile, 1, count); 
  554. if (rename (szFile, newpath)) 
  555. msg_error ("Rename failed!\n"); 
  556. goto failed; 
  557.  
  558. SHChangeNotify (SHCNE_ALLEVENTS, 0, 0, 0);  
  559. printf ("Done! %d ms used\n", GetTickCount () - startTime); 
  560. return 0; 
  561.  
  562. failed: 
  563.  
  564. close (); 
  565. if (files_created) 
  566. for (i = 2; i <= count; ++i) 
  567. sprintf (newpath, "%s.part%d-%d.zeal", szFile, i, count); 
  568. remove (newpath); 
  569.  
  570. return -1;  
  571.  
  572. int zeal::open (char vol) 
  573. if (m_bOpen) 
  574. close (); 
  575.  
  576. char volname[] = "\\\\.\\A:"
  577. volname[4] = vol; 
  578. m_hVol = CreateFile (volname,  
  579. GENERIC_READ | GENERIC_WRITE, 
  580. FILE_SHARE_READ | FILE_SHARE_WRITE, 
  581. NULL, 
  582. OPEN_EXISTING, 
  583. FILE_FLAG_NO_BUFFERING, 
  584. NULL 
  585. ); 
  586.  
  587. if (m_hVol == INVALID_HANDLE_VALUE) 
  588. msg_error ("failed to open %s!\n", volname); 
  589. goto failed; 
  590.  
  591. DWORD ret, read, i; 
  592. ret = ReadFile (m_hVol, (PVOID)&m_BootSector, 512, &read, NULL); 
  593. if (!ret || read != 512) 
  594. msg_error ("ReadFile failed!\n"); 
  595. goto failed; 
  596.  
  597. if (strnicmp(m_BootSector.type, "FAT32 ", 8) ||  
  598. m_BootSector.end_flag != 0xAA55) 
  599. msg_error ("Only FAT32 is supported now, NTFS support will come later\n"); 
  600. goto failed; 
  601.  
  602. if (m_BootSector.bytes_per_sector != 512) 
  603. msg_error ("Error: sector size %d!\n", m_BootSector.bytes_per_sector); 
  604. goto failed; 
  605.  
  606. m_ClusterSize = 512 * m_BootSector.sectors_per_cluster; 
  607. m_OffsetFat1 = m_BootSector.reserved_sectors_count * 512; 
  608. m_OffsetFat2 = m_OffsetFat1 + m_BootSector.sectors_per_fat32 * 512; 
  609. m_OffsetCluster0 = m_OffsetFat2 + m_BootSector.sectors_per_fat32 * 512 - 2 * m_ClusterSize; 
  610. m_OffsetRootdir = m_OffsetCluster0 + m_BootSector.rootdir_cluster * m_ClusterSize; 
  611. m_vol = vol; 
  612. m_bOpen = true
  613. m_arryFatCache = new DWORD [m_BootSector.sectors_per_fat32 * 128]; 
  614. for (i = 0; i < m_BootSector.sectors_per_fat32 * 128; ++i) 
  615. m_arryFatCache[i] = 1; 
  616. return 0; 
  617.  
  618. failed: 
  619. if (m_hVol != INVALID_HANDLE_VALUE) 
  620. CloseHandle (m_hVol); 
  621. return -1; 
  622.  
  623. void zeal::close () 
  624. if (m_bOpen) 
  625. CloseHandle (m_hVol); 
  626. delete[] m_arryFatCache; 
  627. m_bOpen = false
  628.  
  629.  
  630. void Logo () 
  631. puts ("Roger's Zeal for fat32"); 
  632. puts ("Version: 0.11"); 
  633. puts ("Mailto : [email protected]"); 
  634. puts ("Blog : http://rogerfd.cn\n"); 
  635.  
  636. void Usage () 
  637. puts ("Zeal is a in-place file spiltter "); 
  638. puts ("Usage: zeal.exe file_to_split(full path) count "); 
  639. puts (" zeal.exe file_to_restore(any piece) "); 
  640.  
  641.  
  642. int main (int argc, char* argv[]) 
  643. Logo (); 
  644. zeal z; 
  645. if (argc < 2 || argc > 3) 
  646. Usage (); 
  647. return 0; 
  648. #ifdef _DEBUG 
  649. z.set_debug (true); 
  650. #else 
  651. z.set_debug (false); 
  652. #endif 
  653. if (argc == 3) 
  654. z.cut (argv[1], atoi(argv[2])); 
  655. if (argc == 2) 
  656. z.restore (argv[1]); 
  657. return 0; 

你可能感兴趣的:(工具,分割)