Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

823 lines
20 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. fsfile.c
  5. Abstract:
  6. This file contains code for commands that affect
  7. individual files.
  8. Author:
  9. Wesley Witt [wesw] 1-March-2000
  10. Revision History:
  11. --*/
  12. #include <precomp.h>
  13. //----------------------------------
  14. #include <stdlib.h>
  15. #include <limits.h>
  16. #include <errno.h>
  17. #include <ctype.h>
  18. #define MAX_ALLOC_RANGES 32
  19. //
  20. // Common command line args
  21. //
  22. #define ARG_OFFSET L"offset="
  23. #define ARG_OFFSET_LEN 7
  24. #define ARG_LENGTH L"length="
  25. #define ARG_LENGTH_LEN 7
  26. INT
  27. FileHelp(
  28. IN INT argc,
  29. IN PWSTR argv[]
  30. )
  31. {
  32. DisplayMsg( MSG_USAGE_FILE );
  33. return EXIT_CODE_SUCCESS;
  34. }
  35. INT
  36. FindFilesBySid(
  37. IN INT argc,
  38. IN PWSTR argv[]
  39. )
  40. /*++
  41. Routine Description:
  42. This routine finds file owned by the user specified.
  43. Arguments:
  44. argc - The argument count.
  45. argv - Array of Strings of the form :
  46. ' fscutl findbysid <user> <pathname>'.
  47. Return Value:
  48. None
  49. --*/
  50. {
  51. #define SID_MAX_LENGTH (FIELD_OFFSET(SID, SubAuthority) + sizeof(ULONG) * SID_MAX_SUB_AUTHORITIES)
  52. HANDLE FileHandle = INVALID_HANDLE_VALUE;
  53. BOOL Status;
  54. struct {
  55. ULONG Restart;
  56. BYTE Sid[SID_MAX_LENGTH];
  57. } InBuffer;
  58. DWORD nInBufferSize;
  59. DWORD BytesReturned;
  60. ULONG SidLength = sizeof( InBuffer.Sid );
  61. WCHAR Domain[MAX_PATH];
  62. ULONG DomainLength = sizeof( Domain );
  63. SID_NAME_USE SidNameUse;
  64. DWORD nOutBufferSize;
  65. PBYTE lpOutBuffer;
  66. PFILE_NAME_INFORMATION FileNameInfo;
  67. ULONG Length;
  68. PWSTR Filename;
  69. ULONG Found = 0;
  70. INT ExitCode = EXIT_CODE_SUCCESS;
  71. try {
  72. if (argc != 2) {
  73. DisplayMsg( MSG_USAGE_FINDBYSID );
  74. if (argc != 0) {
  75. ExitCode = EXIT_CODE_FAILURE;
  76. }
  77. leave;
  78. }
  79. Filename = GetFullPath( argv[1] );
  80. if (!Filename) {
  81. DisplayError();
  82. ExitCode = EXIT_CODE_FAILURE;
  83. leave;
  84. }
  85. if (!IsVolumeLocalNTFS( Filename[0] )) {
  86. DisplayMsg( MSG_NTFS_REQUIRED );
  87. ExitCode = EXIT_CODE_FAILURE;
  88. leave;
  89. }
  90. FileHandle = CreateFile(
  91. Filename,
  92. GENERIC_READ,
  93. FILE_SHARE_READ | FILE_SHARE_WRITE,
  94. NULL,
  95. OPEN_EXISTING,
  96. FILE_FLAG_BACKUP_SEMANTICS,
  97. NULL
  98. );
  99. if (FileHandle == INVALID_HANDLE_VALUE) {
  100. DisplayError();
  101. ExitCode = EXIT_CODE_FAILURE;
  102. leave;
  103. }
  104. nInBufferSize = sizeof(InBuffer);
  105. nOutBufferSize = 32768;
  106. lpOutBuffer = (PBYTE) malloc( nOutBufferSize );
  107. if (lpOutBuffer == NULL) {
  108. DisplayErrorMsg( ERROR_NOT_ENOUGH_MEMORY );
  109. ExitCode = EXIT_CODE_FAILURE;
  110. leave;
  111. }
  112. memset( lpOutBuffer, 0, nOutBufferSize );
  113. memset( &InBuffer, 0, sizeof(InBuffer) );
  114. if (!LookupAccountName(
  115. NULL,
  116. argv[0],
  117. InBuffer.Sid,
  118. &SidLength,
  119. Domain,
  120. &DomainLength,
  121. &SidNameUse
  122. ))
  123. {
  124. DisplayError();
  125. ExitCode = EXIT_CODE_FAILURE;
  126. leave;
  127. }
  128. InBuffer.Restart = 1;
  129. do {
  130. Status = DeviceIoControl(
  131. FileHandle,
  132. FSCTL_FIND_FILES_BY_SID,
  133. &InBuffer,
  134. nInBufferSize,
  135. lpOutBuffer,
  136. nOutBufferSize,
  137. &BytesReturned,
  138. (LPOVERLAPPED)NULL
  139. );
  140. if (!Status) {
  141. DisplayError();
  142. ExitCode = EXIT_CODE_FAILURE;
  143. leave;
  144. }
  145. InBuffer.Restart = 0;
  146. FileNameInfo = (PFILE_NAME_INFORMATION) lpOutBuffer;
  147. while ((PBYTE)FileNameInfo < lpOutBuffer + BytesReturned) {
  148. Length = sizeof( FILE_NAME_INFORMATION ) - sizeof( WCHAR ) + FileNameInfo->FileNameLength;
  149. OutputMessageLength( FileNameInfo->FileName, FileNameInfo->FileNameLength / sizeof( WCHAR ));
  150. OutputMessage( L"\r\n" );
  151. FileNameInfo = (PFILE_NAME_INFORMATION) Add2Ptr( FileNameInfo, QuadAlign( Length ) );
  152. Found += 1;
  153. }
  154. } while (Status && BytesReturned);
  155. if (Found == 0) {
  156. DisplayMsg( MSG_FINDFILESBYSID_NONE );
  157. }
  158. } finally {
  159. if (FileHandle != INVALID_HANDLE_VALUE) {
  160. CloseHandle( FileHandle );
  161. }
  162. free( lpOutBuffer );
  163. free( Filename );
  164. }
  165. return ExitCode;
  166. }
  167. INT
  168. SetZeroData(
  169. IN INT argc,
  170. IN PWSTR argv[]
  171. )
  172. /*++
  173. Routine Description:
  174. This routine sets zero data for the range in the file specified.
  175. Arguments:
  176. argc - The argument count.
  177. argv - Array of Strings of the form :
  178. ' fscutl setzero offset=<val> beyond=<val> <pathname>'.
  179. Return Value:
  180. None
  181. --*/
  182. {
  183. HANDLE FileHandle = INVALID_HANDLE_VALUE;
  184. PWSTR Filename = NULL;
  185. PWSTR EndPtr;
  186. BOOL Status;
  187. PFILE_ZERO_DATA_INFORMATION lpInBuffer;
  188. DWORD nInBufferSize;
  189. DWORD BytesReturned;
  190. ULONGLONG Offset;
  191. ULONGLONG Length;
  192. ULONGLONG Beyond;
  193. INT ExitCode = EXIT_CODE_SUCCESS;
  194. try {
  195. if (argc != 3) {
  196. DisplayMsg( MSG_SETZERO_USAGE );
  197. if (argc != 0) {
  198. ExitCode = EXIT_CODE_FAILURE;
  199. }
  200. leave;
  201. }
  202. Filename = GetFullPath( argv[2] );
  203. if (!Filename) {
  204. DisplayError();
  205. ExitCode = EXIT_CODE_FAILURE;
  206. leave;
  207. }
  208. if (!IsVolumeLocalNTFS( Filename[0] )) {
  209. DisplayMsg( MSG_NTFS_REQUIRED );
  210. ExitCode = EXIT_CODE_FAILURE;
  211. leave;
  212. }
  213. FileHandle = CreateFile(
  214. Filename,
  215. GENERIC_WRITE,
  216. FILE_SHARE_READ | FILE_SHARE_WRITE,
  217. NULL,
  218. OPEN_EXISTING,
  219. FILE_ATTRIBUTE_NORMAL,
  220. NULL
  221. );
  222. if (FileHandle == INVALID_HANDLE_VALUE) {
  223. DisplayError();
  224. ExitCode = EXIT_CODE_FAILURE;
  225. leave;
  226. }
  227. if (_wcsnicmp( argv[0], ARG_OFFSET, ARG_OFFSET_LEN)) {
  228. DisplayMsg( MSG_SETZERO_USAGE );
  229. ExitCode = EXIT_CODE_FAILURE;
  230. leave;
  231. }
  232. Offset = My_wcstoui64( argv[0] + ARG_OFFSET_LEN, &EndPtr, 0 );
  233. if (UnsignedI64NumberCheck( Offset, EndPtr )) {
  234. DisplayMsg( MSG_SETZERO_USAGE );
  235. ExitCode = EXIT_CODE_FAILURE;
  236. leave;
  237. }
  238. if (_wcsnicmp( argv[1], ARG_LENGTH, ARG_LENGTH_LEN)) {
  239. DisplayMsg( MSG_SETZERO_USAGE );
  240. ExitCode = EXIT_CODE_FAILURE;
  241. leave;
  242. }
  243. Length = My_wcstoui64( argv[1] + ARG_LENGTH_LEN, &EndPtr, 0 );
  244. if (UnsignedI64NumberCheck( Length, EndPtr )) {
  245. DisplayMsg( MSG_SETZERO_USAGE );
  246. ExitCode = EXIT_CODE_FAILURE;
  247. leave;
  248. }
  249. Beyond = Offset + Length;
  250. if (Beyond < Offset) {
  251. DisplayMsg( MSG_SETZERO_USAGE );
  252. ExitCode = EXIT_CODE_FAILURE;
  253. leave;
  254. }
  255. nInBufferSize = sizeof(FILE_ZERO_DATA_INFORMATION);
  256. lpInBuffer = (PFILE_ZERO_DATA_INFORMATION) malloc ( nInBufferSize );
  257. if (lpInBuffer == NULL) {
  258. DisplayErrorMsg( ERROR_NOT_ENOUGH_MEMORY );
  259. ExitCode = EXIT_CODE_FAILURE;
  260. leave;
  261. }
  262. lpInBuffer->FileOffset.QuadPart = Offset;
  263. lpInBuffer->BeyondFinalZero.QuadPart = Beyond;
  264. Status = DeviceIoControl(
  265. FileHandle,
  266. FSCTL_SET_ZERO_DATA,
  267. (LPVOID) lpInBuffer,
  268. nInBufferSize,
  269. NULL,
  270. 0,
  271. &BytesReturned,
  272. (LPOVERLAPPED)NULL
  273. );
  274. if (!Status) {
  275. DisplayError();
  276. ExitCode = EXIT_CODE_FAILURE;
  277. } else {
  278. DisplayMsg( MSG_SET_ZERODATA );
  279. }
  280. } finally {
  281. if (FileHandle != INVALID_HANDLE_VALUE) {
  282. CloseHandle( FileHandle );
  283. }
  284. if (Filename) {
  285. free( Filename );
  286. }
  287. }
  288. return ExitCode;
  289. }
  290. INT
  291. QueryAllocatedRanges(
  292. IN INT argc,
  293. IN PWSTR argv[]
  294. )
  295. /*++
  296. Routine Description:
  297. This routine scans for any allocated range within the range
  298. specified in the file specified.
  299. Arguments:
  300. argc - The argument count.
  301. argv - Array of Strings of the form :
  302. ' fscutl qryalcrnge offset=<val> length=<val> <pathname>'.
  303. Return Value:
  304. None
  305. --*/
  306. {
  307. HANDLE FileHandle = INVALID_HANDLE_VALUE;
  308. PWSTR Filename = NULL;
  309. PWSTR EndPtr;
  310. BOOL Status;
  311. PFILE_ALLOCATED_RANGE_BUFFER lpInBuffer = NULL;
  312. DWORD nInBufferSize;
  313. PFILE_ALLOCATED_RANGE_BUFFER *lpOutBuffer = NULL;
  314. PFILE_ALLOCATED_RANGE_BUFFER pBuffer;
  315. DWORD nOutBufferSize;
  316. DWORD BytesReturned;
  317. ULARGE_INTEGER Offset;
  318. ULARGE_INTEGER Length;
  319. INT NumberOfBuffers;
  320. INT Index;
  321. INT ExitCode = EXIT_CODE_SUCCESS;
  322. try {
  323. if (argc != 3) {
  324. DisplayMsg( MSG_ALLOCRANGE_USAGE );
  325. if (argc != 0) {
  326. ExitCode = EXIT_CODE_FAILURE;
  327. }
  328. leave;
  329. }
  330. Filename = GetFullPath( argv[2] );
  331. if (!Filename) {
  332. DisplayError();
  333. ExitCode = EXIT_CODE_FAILURE;
  334. leave;
  335. }
  336. if (!IsVolumeLocalNTFS( Filename[0] )) {
  337. DisplayMsg( MSG_NTFS_REQUIRED );
  338. ExitCode = EXIT_CODE_FAILURE;
  339. leave;
  340. }
  341. Offset.QuadPart = Length.QuadPart = 0;
  342. if (_wcsnicmp( argv[0], ARG_OFFSET, ARG_OFFSET_LEN )) {
  343. DisplayMsg( MSG_ALLOCRANGE_USAGE );
  344. ExitCode = EXIT_CODE_FAILURE;
  345. leave;
  346. }
  347. Offset.QuadPart = My_wcstoui64( argv[0] + ARG_OFFSET_LEN, &EndPtr, 0 );
  348. if (UnsignedI64NumberCheck( Offset.QuadPart, EndPtr)) {
  349. DisplayMsg( MSG_ALLOCRANGE_USAGE );
  350. ExitCode = EXIT_CODE_FAILURE;
  351. leave;
  352. }
  353. if (_wcsnicmp( argv[1], ARG_LENGTH, ARG_LENGTH_LEN )) {
  354. DisplayMsg( MSG_ALLOCRANGE_USAGE );
  355. ExitCode = EXIT_CODE_FAILURE;
  356. leave;
  357. }
  358. Length.QuadPart = My_wcstoui64( argv[1] + ARG_LENGTH_LEN, &EndPtr, 0 );
  359. if (UnsignedI64NumberCheck( Length.QuadPart, EndPtr )) {
  360. DisplayMsg( MSG_ALLOCRANGE_USAGE );
  361. ExitCode = EXIT_CODE_FAILURE;
  362. leave;
  363. }
  364. FileHandle = CreateFile(
  365. Filename,
  366. GENERIC_READ,
  367. FILE_SHARE_READ | FILE_SHARE_WRITE,
  368. NULL,
  369. OPEN_EXISTING,
  370. FILE_ATTRIBUTE_NORMAL,
  371. NULL
  372. );
  373. if (FileHandle == INVALID_HANDLE_VALUE) {
  374. DisplayError();
  375. ExitCode = EXIT_CODE_FAILURE;
  376. leave;
  377. }
  378. nInBufferSize = sizeof(FILE_ALLOCATED_RANGE_BUFFER);
  379. lpInBuffer = (PFILE_ALLOCATED_RANGE_BUFFER) malloc ( nInBufferSize );
  380. nOutBufferSize = sizeof(FILE_ALLOCATED_RANGE_BUFFER) * MAX_ALLOC_RANGES;
  381. lpOutBuffer = (PFILE_ALLOCATED_RANGE_BUFFER *) calloc ( MAX_ALLOC_RANGES, sizeof(FILE_ALLOCATED_RANGE_BUFFER) );
  382. if (lpInBuffer == NULL || lpOutBuffer == NULL) {
  383. DisplayErrorMsg( ERROR_NOT_ENOUGH_MEMORY );
  384. ExitCode = EXIT_CODE_FAILURE;
  385. leave;
  386. }
  387. lpInBuffer->FileOffset.QuadPart = Offset.QuadPart;
  388. lpInBuffer->Length.QuadPart = Length.QuadPart;
  389. Status = DeviceIoControl(
  390. FileHandle,
  391. FSCTL_QUERY_ALLOCATED_RANGES,
  392. (LPVOID) lpInBuffer,
  393. nInBufferSize,
  394. lpOutBuffer,
  395. nOutBufferSize,
  396. &BytesReturned,
  397. (LPOVERLAPPED)NULL
  398. );
  399. if (!Status) {
  400. DisplayError();
  401. ExitCode = EXIT_CODE_FAILURE;
  402. leave;
  403. }
  404. pBuffer = (PFILE_ALLOCATED_RANGE_BUFFER) lpOutBuffer ;
  405. NumberOfBuffers = (BytesReturned) / sizeof(FILE_ALLOCATED_RANGE_BUFFER);
  406. for ( Index=0; Index<NumberOfBuffers; Index++ ) {
  407. DisplayMsg( MSG_ALLOCRANGE_RANGES, Index, QuadToHexText( pBuffer[Index].FileOffset.QuadPart ), QuadToHexText( pBuffer[Index].Length.QuadPart ));
  408. }
  409. } finally {
  410. if (FileHandle != INVALID_HANDLE_VALUE) {
  411. CloseHandle( FileHandle );
  412. }
  413. free( Filename );
  414. free( lpInBuffer );
  415. free( lpOutBuffer );
  416. }
  417. return ExitCode;
  418. }
  419. typedef BOOL
  420. (WINAPI *PSETFILEVALIDDATA)(
  421. IN HANDLE hFile,
  422. IN LONGLONG ValidDataLength
  423. );
  424. PSETFILEVALIDDATA pSetFileValidData = NULL;
  425. BOOL WINAPI
  426. DefaultSetFileValidData(
  427. IN HANDLE hFile,
  428. IN LONGLONG ValidDataLength
  429. )
  430. {
  431. return FALSE;
  432. }
  433. INT
  434. SetValidDataLength(
  435. IN INT argc,
  436. IN PWSTR argv[]
  437. )
  438. {
  439. HANDLE hFile = INVALID_HANDLE_VALUE;
  440. PWSTR Filename = NULL;
  441. INT ExitCode = EXIT_CODE_SUCCESS;
  442. try {
  443. if (argc != 2) {
  444. DisplayMsg( MSG_USAGE_VALID_DATA );
  445. if (argc != 0) {
  446. ExitCode = EXIT_CODE_FAILURE;
  447. }
  448. leave ;
  449. }
  450. Filename = GetFullPath( argv[0] );
  451. if (!Filename) {
  452. DisplayError();
  453. ExitCode = EXIT_CODE_FAILURE;
  454. leave;
  455. }
  456. if (!IsVolumeLocalNTFS( Filename[0] )) {
  457. DisplayMsg( MSG_NTFS_REQUIRED );
  458. ExitCode = EXIT_CODE_FAILURE;
  459. leave;
  460. }
  461. if(!EnablePrivilege( SE_MANAGE_VOLUME_NAME )) {
  462. DisplayError( );
  463. ExitCode = EXIT_CODE_FAILURE;
  464. leave;
  465. }
  466. hFile = CreateFile(
  467. Filename,
  468. GENERIC_READ | GENERIC_WRITE | GENERIC_ALL,
  469. FILE_SHARE_READ | FILE_SHARE_WRITE,
  470. NULL,
  471. OPEN_EXISTING,
  472. FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS,
  473. NULL
  474. );
  475. if (hFile == INVALID_HANDLE_VALUE) {
  476. DisplayError();
  477. ExitCode = EXIT_CODE_FAILURE;
  478. leave;
  479. }
  480. if (!RunningOnWin2K) {
  481. LONGLONG ValidDataLength;
  482. PWSTR EndStr;
  483. if (pSetFileValidData == NULL) {
  484. pSetFileValidData = (PSETFILEVALIDDATA) GetProcAddress( GetModuleHandle(L"KERNEL32.DLL"), "SetFileValidData" );
  485. } else {
  486. pSetFileValidData = DefaultSetFileValidData;
  487. }
  488. ValidDataLength = My_wcstoui64( argv[1], &EndStr, 0 );
  489. if (UnsignedI64NumberCheck( ValidDataLength, EndStr )
  490. || !pSetFileValidData( hFile, ValidDataLength)
  491. ) {
  492. DisplayError( );
  493. ExitCode = EXIT_CODE_FAILURE;
  494. } else {
  495. DisplayMsg( MSG_SET_VDL );
  496. }
  497. }
  498. } finally {
  499. if (hFile != INVALID_HANDLE_VALUE) {
  500. CloseHandle( hFile );
  501. }
  502. free( Filename );
  503. }
  504. return ExitCode;
  505. }
  506. typedef BOOL
  507. (WINAPI *PSETFILESHORTNAMEW)(
  508. IN HANDLE hFile,
  509. IN LPCWSTR lpShortName
  510. );
  511. BOOL WINAPI
  512. DoNothingSetShortName(
  513. IN HANDLE hFile,
  514. IN LPCWSTR lpShortName
  515. )
  516. {
  517. return FALSE;
  518. }
  519. BOOL WINAPI
  520. InitialSetShortName(
  521. IN HANDLE hFile,
  522. IN LPCWSTR lpShortName
  523. );
  524. PSETFILESHORTNAMEW pSetFileShortName = InitialSetShortName;
  525. BOOL WINAPI
  526. InitialSetShortName(
  527. IN HANDLE hFile,
  528. IN LPCWSTR lpShortName
  529. )
  530. {
  531. HANDLE Handle = GetModuleHandle( L"KERNEL32.DLL" );
  532. FARPROC Proc;
  533. if (Handle == INVALID_HANDLE_VALUE) {
  534. pSetFileShortName = DoNothingSetShortName;
  535. } else if ((Proc = GetProcAddress( Handle, "SetFileShortNameW" )) != NULL) {
  536. pSetFileShortName = (PSETFILESHORTNAMEW) Proc;
  537. } else {
  538. pSetFileShortName = DoNothingSetShortName;
  539. }
  540. return pSetFileShortName( hFile, lpShortName );
  541. }
  542. INT
  543. SetShortName(
  544. IN INT argc,
  545. IN PWSTR argv[]
  546. )
  547. {
  548. HANDLE hFile = INVALID_HANDLE_VALUE;
  549. PWSTR Filename = NULL;
  550. INT ExitCode = EXIT_CODE_SUCCESS;
  551. try {
  552. if (argc != 2) {
  553. DisplayMsg( MSG_USAGE_SHORTNAME, argv[1] );
  554. if (argc != 0) {
  555. ExitCode = EXIT_CODE_FAILURE;
  556. }
  557. leave ;
  558. }
  559. Filename = GetFullPath( argv[0] );
  560. if (!Filename) {
  561. DisplayError();
  562. ExitCode = EXIT_CODE_FAILURE;
  563. leave;
  564. }
  565. if (!IsVolumeLocalNTFS( Filename[0] )) {
  566. DisplayMsg( MSG_NTFS_REQUIRED );
  567. ExitCode = EXIT_CODE_FAILURE;
  568. leave;
  569. }
  570. if (!EnablePrivilege( SE_RESTORE_NAME )) {
  571. DisplayError( );
  572. ExitCode = EXIT_CODE_FAILURE;
  573. leave;
  574. }
  575. hFile = CreateFile(
  576. Filename,
  577. GENERIC_READ | GENERIC_WRITE | GENERIC_ALL,
  578. FILE_SHARE_READ | FILE_SHARE_WRITE,
  579. NULL,
  580. OPEN_EXISTING,
  581. FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS,
  582. NULL
  583. );
  584. if (hFile == INVALID_HANDLE_VALUE) {
  585. DisplayError();
  586. ExitCode = EXIT_CODE_FAILURE;
  587. leave;
  588. }
  589. if (!RunningOnWin2K) {
  590. if (!pSetFileShortName( hFile, argv[1] )) {
  591. DisplayError();
  592. ExitCode = EXIT_CODE_FAILURE;
  593. }
  594. }
  595. } finally {
  596. if (hFile != INVALID_HANDLE_VALUE) {
  597. CloseHandle( hFile );
  598. }
  599. free( Filename );
  600. }
  601. return ExitCode;
  602. }
  603. INT
  604. CreateNewFile(
  605. IN INT argc,
  606. IN PWSTR argv[]
  607. )
  608. {
  609. HANDLE hFile = INVALID_HANDLE_VALUE;
  610. PWSTR Filename = NULL;
  611. LARGE_INTEGER Length;
  612. BOOL GoodFile = TRUE;
  613. INT ExitCode = EXIT_CODE_SUCCESS;
  614. try {
  615. PWSTR EndPtr;
  616. if (argc != 2) {
  617. DisplayMsg( MSG_USAGE_CREATEFILE, argv[1] );
  618. if (argc != 0) {
  619. ExitCode = EXIT_CODE_FAILURE;
  620. }
  621. leave ;
  622. }
  623. Filename = GetFullPath( argv[0] );
  624. if (!Filename) {
  625. DisplayError();
  626. ExitCode = EXIT_CODE_FAILURE;
  627. leave;
  628. }
  629. Length.QuadPart = My_wcstoui64( argv[1], &EndPtr, 0 );
  630. if (UnsignedI64NumberCheck( Length.QuadPart, EndPtr )) {
  631. DisplayMsg( MSG_USAGE_CREATEFILE, argv[1] );
  632. ExitCode = EXIT_CODE_FAILURE;
  633. leave;
  634. }
  635. hFile = CreateFile(
  636. Filename,
  637. GENERIC_READ | GENERIC_WRITE | GENERIC_ALL,
  638. 0,
  639. NULL,
  640. CREATE_NEW,
  641. FILE_ATTRIBUTE_NORMAL,
  642. NULL
  643. );
  644. if (hFile == INVALID_HANDLE_VALUE) {
  645. DisplayError();
  646. ExitCode = EXIT_CODE_FAILURE;
  647. leave;
  648. }
  649. GoodFile = FALSE;
  650. if (!SetFilePointerEx( hFile, Length, NULL, FILE_BEGIN )) {
  651. DisplayError();
  652. ExitCode = EXIT_CODE_FAILURE;
  653. leave;
  654. }
  655. if (!SetEndOfFile( hFile )) {
  656. DisplayError();
  657. ExitCode = EXIT_CODE_FAILURE;
  658. leave;
  659. }
  660. GoodFile = TRUE;
  661. DisplayMsg( MSG_CREATEFILE_SUCCEEDED, Filename );
  662. } finally {
  663. if (hFile != INVALID_HANDLE_VALUE) {
  664. CloseHandle( hFile );
  665. }
  666. if (!GoodFile) {
  667. DeleteFile( Filename );
  668. }
  669. free( Filename );
  670. }
  671. return ExitCode;
  672. }