Source code of Windows XP (NT5)
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.

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