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.

1188 lines
34 KiB

  1. /*++
  2. Copyright (c) 1998 Microsoft Corporation
  3. Module Name:
  4. mountie.c
  5. Abstract:
  6. Abstract
  7. Author:
  8. Rod Gamache (rodga) 4-Mar-1998
  9. Environment:
  10. User Mode
  11. Revision History:
  12. --*/
  13. #include <nt.h>
  14. #include <ntdef.h>
  15. #include <ntrtl.h>
  16. #include <nturtl.h>
  17. #include <windows.h>
  18. #include <devioctl.h>
  19. //#include <ntdddisk.h>
  20. //#include <ntddscsi.h>
  21. #include <stdio.h>
  22. #include <stddef.h>
  23. #include <stdlib.h>
  24. #include <cfgmgr32.h>
  25. #include <mountmgr.h>
  26. #include "disksp.h"
  27. #include "mountie.h"
  28. #define OUTPUT_BUFFER_LEN 1024
  29. /*
  30. * DevfileOpen - open a device file given a pathname
  31. *
  32. * Return a non-zero code for error.
  33. */
  34. DWORD
  35. DevfileOpen(
  36. OUT HANDLE *Handle,
  37. IN wchar_t *pathname
  38. )
  39. {
  40. HANDLE fh;
  41. OBJECT_ATTRIBUTES objattrs;
  42. UNICODE_STRING cwspath;
  43. NTSTATUS status;
  44. IO_STATUS_BLOCK iostatus;
  45. RtlInitUnicodeString(&cwspath, pathname);
  46. InitializeObjectAttributes(&objattrs, &cwspath, OBJ_CASE_INSENSITIVE,
  47. NULL, NULL);
  48. fh = NULL;
  49. status = NtOpenFile(&fh,
  50. SYNCHRONIZE | FILE_READ_DATA | FILE_WRITE_DATA,
  51. &objattrs, &iostatus,
  52. FILE_SHARE_READ | FILE_SHARE_WRITE,
  53. FILE_SYNCHRONOUS_IO_ALERT);
  54. if (status != STATUS_SUCCESS) {
  55. return status;
  56. }
  57. if (iostatus.Status != STATUS_SUCCESS) {
  58. if (fh) {
  59. NtClose(fh);
  60. }
  61. return iostatus.Status;
  62. }
  63. *Handle = fh;
  64. return STATUS_SUCCESS;
  65. } // DevfileOpen
  66. /*
  67. * DevfileClose - close a file
  68. */
  69. VOID
  70. DevfileClose(
  71. IN HANDLE Handle
  72. )
  73. {
  74. NtClose(Handle);
  75. } // DevFileClose
  76. /*
  77. * DevfileIoctl - issue an ioctl to a device
  78. */
  79. DWORD
  80. DevfileIoctl(
  81. IN HANDLE Handle,
  82. IN DWORD Ioctl,
  83. IN PVOID InBuf,
  84. IN ULONG InBufSize,
  85. IN OUT PVOID OutBuf,
  86. IN DWORD OutBufSize,
  87. OUT LPDWORD returnLength
  88. )
  89. {
  90. NTSTATUS status;
  91. IO_STATUS_BLOCK ioStatus;
  92. status = NtDeviceIoControlFile(Handle,
  93. (HANDLE) NULL,
  94. (PIO_APC_ROUTINE) NULL,
  95. NULL,
  96. &ioStatus,
  97. Ioctl,
  98. InBuf, InBufSize,
  99. OutBuf, OutBufSize);
  100. if ( status == STATUS_PENDING ) {
  101. status = NtWaitForSingleObject( Handle, FALSE, NULL );
  102. }
  103. if ( NT_SUCCESS(status) ) {
  104. status = ioStatus.Status;
  105. }
  106. if ( ARGUMENT_PRESENT(returnLength) ) {
  107. *returnLength = (DWORD)ioStatus.Information;
  108. }
  109. return status;
  110. } // DevfileIoctl
  111. DWORD
  112. DisksAssignDosDevice(
  113. PCHAR MountName,
  114. PWCHAR VolumeDevName
  115. )
  116. /*++
  117. Routine Description:
  118. Inputs:
  119. MountName -
  120. VolumeDevName -
  121. Return value:
  122. A Win32 error code.
  123. --*/
  124. {
  125. WCHAR mount_device[MAX_PATH];
  126. USHORT mount_point_len;
  127. USHORT dev_name_len;
  128. HANDLE handle;
  129. DWORD status;
  130. USHORT inputlength;
  131. PMOUNTMGR_CREATE_POINT_INPUT input;
  132. status = DevfileOpen(&handle, MOUNTMGR_DEVICE_NAME);
  133. if (status) {
  134. return status;
  135. }
  136. swprintf(mount_device, L"\\DosDevices\\%S", MountName);
  137. mount_point_len = wcslen(mount_device) * sizeof(WCHAR);
  138. dev_name_len = wcslen(VolumeDevName) * sizeof(WCHAR);
  139. inputlength = sizeof(MOUNTMGR_CREATE_POINT_INPUT) +
  140. mount_point_len + dev_name_len;
  141. input = (PMOUNTMGR_CREATE_POINT_INPUT)malloc(inputlength);
  142. if (!input) {
  143. DevfileClose(handle);
  144. return ERROR_NOT_ENOUGH_MEMORY;
  145. }
  146. input->SymbolicLinkNameOffset = sizeof(MOUNTMGR_CREATE_POINT_INPUT);
  147. input->SymbolicLinkNameLength = mount_point_len;
  148. input->DeviceNameOffset = input->SymbolicLinkNameOffset +
  149. input->SymbolicLinkNameLength;
  150. input->DeviceNameLength = dev_name_len;
  151. RtlCopyMemory((PCHAR)input + input->SymbolicLinkNameOffset,
  152. mount_device, mount_point_len);
  153. RtlCopyMemory((PCHAR)input + input->DeviceNameOffset,
  154. VolumeDevName, dev_name_len);
  155. status = DevfileIoctl(handle, IOCTL_MOUNTMGR_CREATE_POINT,
  156. input, inputlength, NULL, 0, NULL);
  157. free(input);
  158. DevfileClose(handle);
  159. return status;
  160. } // DisksAssignDosDevice
  161. DWORD
  162. DisksRemoveDosDevice(
  163. PCHAR MountName
  164. )
  165. /*++
  166. Routine Description:
  167. Inputs:
  168. MountName -
  169. Return value:
  170. --*/
  171. {
  172. WCHAR mount_device[MAX_PATH];
  173. USHORT mount_point_len;
  174. USHORT dev_name_len;
  175. HANDLE handle;
  176. DWORD status;
  177. USHORT inputlength;
  178. PMOUNTMGR_MOUNT_POINT input;
  179. UCHAR bogusBuffer[128];
  180. status = DevfileOpen(&handle, MOUNTMGR_DEVICE_NAME);
  181. if (status) {
  182. return status;
  183. }
  184. swprintf(mount_device, L"\\DosDevices\\%S", MountName);
  185. mount_point_len = wcslen(mount_device) * sizeof(WCHAR);
  186. inputlength = sizeof(MOUNTMGR_MOUNT_POINT) + mount_point_len;
  187. input = (PMOUNTMGR_MOUNT_POINT)malloc(inputlength);
  188. if (!input) {
  189. DevfileClose(handle);
  190. return ERROR_NOT_ENOUGH_MEMORY;
  191. }
  192. input->UniqueIdOffset = 0;
  193. input->UniqueIdLength = 0;
  194. input->DeviceNameOffset = 0;
  195. input->DeviceNameLength = 0;
  196. input->SymbolicLinkNameOffset = sizeof(MOUNTMGR_MOUNT_POINT);
  197. input->SymbolicLinkNameLength = mount_point_len;
  198. RtlCopyMemory((PCHAR)input + input->SymbolicLinkNameOffset,
  199. mount_device, mount_point_len);
  200. status = DevfileIoctl(handle, IOCTL_MOUNTMGR_DELETE_POINTS,
  201. input, inputlength, bogusBuffer, 128, NULL);
  202. free(input);
  203. DevfileClose(handle);
  204. return status;
  205. } // DisksRemoveDosDevice
  206. DWORD
  207. FindFirstVolumeForSignature(
  208. IN HANDLE MountMgrHandle,
  209. IN DWORD Signature,
  210. OUT LPSTR VolumeName,
  211. IN DWORD BufferLength,
  212. OUT LPHANDLE Handle,
  213. OUT PVOID UniqueId OPTIONAL,
  214. IN OUT LPDWORD IdLength,
  215. OUT PUCHAR DriveLetter OPTIONAL
  216. )
  217. /*++
  218. Inputs:
  219. MountMgrHandle - a handle to the mount manager.
  220. Signature - the signature we are looking for.
  221. VolumeName - must be a valid buffer of at least MAX_PATH characters.
  222. BufferLength - the length of VolumeName.
  223. Handle - pointer to receive the FindFirstVolume/FindNextVolume enum handle.
  224. UniqueId - optional pointer to buffer to receive the UniqueId.
  225. IdLength - pointer to length of the UniqueId buffer. Must be valid if
  226. UniqueId is present.
  227. DriveLetter - returns the drive letter if present.
  228. Return Value:
  229. Win32 error code
  230. --*/
  231. {
  232. HANDLE handle;
  233. BOOL success;
  234. DWORD status;
  235. LPDWORD idSignature;
  236. DWORD bufLength;
  237. LPWSTR wVolumeName;
  238. DWORD inputlength;
  239. DWORD outputlength;
  240. DWORD returnlength;
  241. UCHAR outputBuffer[OUTPUT_BUFFER_LEN];
  242. PMOUNTMGR_MOUNT_POINT input;
  243. PMOUNTMGR_MOUNT_POINTS output;
  244. PUCHAR byteBuffer;
  245. DWORD mountPoints;
  246. if ( !ARGUMENT_PRESENT( VolumeName ) ) {
  247. return ERROR_INVALID_PARAMETER;
  248. }
  249. handle = FindFirstVolume( VolumeName, BufferLength );
  250. if ( handle == INVALID_HANDLE_VALUE ) {
  251. return(ERROR_FILE_NOT_FOUND);
  252. }
  253. do {
  254. bufLength = strlen( VolumeName );
  255. VolumeName[bufLength-1] = '\0';
  256. if ( VolumeName[1] != '\\' ) {
  257. status = ERROR_INVALID_NAME;
  258. break;
  259. } else {
  260. VolumeName[1] = '?';
  261. wVolumeName = malloc( bufLength * sizeof(WCHAR) );
  262. if (!wVolumeName) {
  263. status = ERROR_NOT_ENOUGH_MEMORY;
  264. break;
  265. }
  266. mbstowcs( wVolumeName, VolumeName, bufLength );
  267. bufLength--;
  268. printf( "\nFound volume %ws\n", wVolumeName );
  269. inputlength = sizeof(MOUNTMGR_MOUNT_POINT) +
  270. (bufLength*sizeof(WCHAR)) + (2*sizeof(WCHAR));
  271. input = (PMOUNTMGR_MOUNT_POINT)malloc(inputlength);
  272. if (!input) {
  273. free( wVolumeName );
  274. status = ERROR_NOT_ENOUGH_MEMORY;
  275. break;
  276. }
  277. input->SymbolicLinkNameOffset = 0;
  278. input->SymbolicLinkNameLength = 0;
  279. input->UniqueIdOffset = 0;
  280. input->UniqueIdLength = 0;
  281. input->DeviceNameOffset = sizeof(MOUNTMGR_MOUNT_POINT);
  282. input->DeviceNameLength = (USHORT)(bufLength * sizeof(WCHAR));
  283. RtlCopyMemory((PCHAR)input + input->DeviceNameOffset,
  284. wVolumeName, bufLength * sizeof(WCHAR) );
  285. outputlength = OUTPUT_BUFFER_LEN;
  286. status = DevfileIoctl(MountMgrHandle, IOCTL_MOUNTMGR_QUERY_POINTS,
  287. input, inputlength, outputBuffer, outputlength, &returnlength);
  288. if ( status != ERROR_SUCCESS ) {
  289. printf( "Query points for %ws failed, error %u\n",
  290. input->DeviceNameOffset, status );
  291. free( wVolumeName );
  292. free(input);
  293. wVolumeName = NULL;
  294. input = NULL;
  295. break;
  296. } else {
  297. output = (PMOUNTMGR_MOUNT_POINTS)outputBuffer;
  298. mountPoints = output->NumberOfMountPoints;
  299. if ( !mountPoints ) {
  300. return ERROR_INVALID_DATA;
  301. }
  302. byteBuffer = outputBuffer + output->MountPoints[0].UniqueIdOffset;
  303. idSignature = (LPDWORD)byteBuffer;
  304. if ( !Signature ||
  305. (Signature == *idSignature) ) {
  306. NTSTATUS ntStatus;
  307. UNICODE_STRING unicodeString;
  308. OEM_STRING oemString;
  309. DWORD count;
  310. UCHAR driveLetter;
  311. UCHAR devName[ MAX_PATH ];
  312. PWCHAR wideBuffer;
  313. LPDWORD dwordBuffer;
  314. free( wVolumeName );
  315. free(input);
  316. input = NULL;
  317. wVolumeName = NULL;
  318. *Handle = handle;
  319. if ( ARGUMENT_PRESENT(UniqueId) ) {
  320. if ( *IdLength > output->MountPoints[0].UniqueIdLength ) {
  321. *IdLength = output->MountPoints[0].UniqueIdLength;
  322. }
  323. RtlCopyMemory( UniqueId, byteBuffer, *IdLength );
  324. }
  325. //
  326. // Print the ID
  327. //
  328. count = output->MountPoints[0].UniqueIdLength;
  329. count = (count + 3) / 4;
  330. dwordBuffer = (LPDWORD)(outputBuffer + output->MountPoints[0].UniqueIdOffset);
  331. printf( "Id = " );
  332. while ( count-- ) {
  333. printf( "%08lx ", *(dwordBuffer++) );
  334. }
  335. printf( "\n" );
  336. if ( ARGUMENT_PRESENT(DriveLetter) ) {
  337. *DriveLetter = 0;
  338. while ( mountPoints-- ) {
  339. byteBuffer = outputBuffer +
  340. output->MountPoints[mountPoints].SymbolicLinkNameOffset;
  341. //
  342. // Covert UNICODE name to OEM string upper case
  343. //
  344. unicodeString.Buffer = (PWCHAR)byteBuffer;
  345. unicodeString.MaximumLength = output->MountPoints[mountPoints].SymbolicLinkNameLength + sizeof(WCHAR);
  346. unicodeString.Length = output->MountPoints[mountPoints].SymbolicLinkNameLength;
  347. oemString.Buffer = devName;
  348. oemString.MaximumLength = sizeof(devName);
  349. ntStatus = RtlUpcaseUnicodeStringToOemString(
  350. &oemString,
  351. &unicodeString,
  352. FALSE );
  353. if ( ntStatus != STATUS_SUCCESS ) {
  354. status = RtlNtStatusToDosError( ntStatus );
  355. return status;
  356. }
  357. devName[oemString.Length] = '\0';
  358. count = sscanf( devName, "\\DOSDEVICES\\%c:", &driveLetter );
  359. wideBuffer = (PWCHAR)byteBuffer;
  360. wideBuffer[(output->MountPoints[mountPoints].SymbolicLinkNameLength)/2] = L'\0';
  361. if ( count ) {
  362. *DriveLetter = driveLetter;
  363. printf( "Symbolic name = %ws, letter = %c:\\\n",
  364. byteBuffer,
  365. driveLetter );
  366. if ( Signature ) {
  367. break;
  368. }
  369. } else {
  370. printf( "Symbolic name = %ws\n",
  371. byteBuffer );
  372. }
  373. }
  374. }
  375. if ( Signature ) {
  376. return ERROR_SUCCESS;
  377. }
  378. }
  379. }
  380. free(wVolumeName);
  381. free(input);
  382. }
  383. success = FindNextVolume( handle,
  384. VolumeName,
  385. BufferLength );
  386. if ( !success ) {
  387. status = GetLastError();
  388. }
  389. } while ( status == ERROR_SUCCESS );
  390. FindVolumeClose( handle );
  391. return status;
  392. } // FindFirstVolumeForSignature
  393. DWORD
  394. FindNextVolumeForSignature(
  395. IN HANDLE MountMgrHandle,
  396. IN DWORD Signature,
  397. IN HANDLE Handle,
  398. OUT LPSTR VolumeName,
  399. IN DWORD BufferLength,
  400. OUT PVOID UniqueId OPTIONAL,
  401. IN OUT LPDWORD IdLength,
  402. OUT PUCHAR DriveLetter OPTIONAL
  403. )
  404. /*++
  405. Inputs:
  406. MountMgrHandle - a handle to the mount manager.
  407. Signature - the signature we are looking for.
  408. Handle - the FindFirstVolume/FindNextVolume enum handle.
  409. VolumeName - must be a valid buffer of at least MAX_PATH characters.
  410. BufferLength - the length of VolumeName.
  411. UniqueId - optional pointer to buffer to receive the UniqueId.
  412. IdLength - point to the length of the UniqueId buffer.
  413. DriveLetter - returns the drive letter if present.
  414. Return Value:
  415. Win32 error code
  416. --*/
  417. {
  418. BOOL success;
  419. DWORD status;
  420. LPDWORD idSignature;
  421. DWORD bufLength;
  422. LPWSTR wVolumeName;
  423. DWORD inputlength;
  424. DWORD outputlength;
  425. DWORD returnlength;
  426. UCHAR outputBuffer[OUTPUT_BUFFER_LEN];
  427. PMOUNTMGR_MOUNT_POINT input;
  428. PMOUNTMGR_MOUNT_POINTS output;
  429. PUCHAR byteBuffer;
  430. DWORD mountPoints;
  431. if ( !ARGUMENT_PRESENT( VolumeName ) ) {
  432. return ERROR_INVALID_PARAMETER;
  433. }
  434. do {
  435. success = FindNextVolume( Handle, VolumeName, BufferLength );
  436. if ( !success ) {
  437. status = GetLastError();
  438. break;
  439. }
  440. bufLength = strlen( VolumeName );
  441. VolumeName[bufLength-1] = '\0';
  442. if ( VolumeName[1] != '\\' ) {
  443. status = ERROR_INVALID_NAME;
  444. break;
  445. } else {
  446. VolumeName[1] = '?';
  447. bufLength--;
  448. wVolumeName = malloc( bufLength * sizeof(WCHAR) );
  449. if (!wVolumeName) {
  450. status = ERROR_NOT_ENOUGH_MEMORY;
  451. break;
  452. }
  453. mbstowcs( wVolumeName, VolumeName, bufLength );
  454. inputlength = sizeof(MOUNTMGR_MOUNT_POINT) +
  455. (bufLength*sizeof(WCHAR)) + (2*sizeof(WCHAR));
  456. input = (PMOUNTMGR_MOUNT_POINT)malloc(inputlength);
  457. if (!input) {
  458. free( wVolumeName );
  459. status = ERROR_NOT_ENOUGH_MEMORY;
  460. break;
  461. }
  462. input->SymbolicLinkNameOffset = 0;
  463. input->SymbolicLinkNameLength = 0;
  464. input->UniqueIdOffset = 0;
  465. input->UniqueIdLength = 0;
  466. input->DeviceNameOffset = sizeof(MOUNTMGR_MOUNT_POINT);
  467. input->DeviceNameLength = (USHORT)(bufLength * sizeof(WCHAR));
  468. RtlCopyMemory((PCHAR)input + input->DeviceNameOffset,
  469. wVolumeName, bufLength * sizeof(WCHAR) );
  470. outputlength = OUTPUT_BUFFER_LEN;
  471. status = DevfileIoctl(MountMgrHandle, IOCTL_MOUNTMGR_QUERY_POINTS,
  472. input, inputlength, outputBuffer, outputlength, &returnlength);
  473. if ( status != ERROR_SUCCESS ) {
  474. free( wVolumeName );
  475. free(input);
  476. break;
  477. } else {
  478. output = (PMOUNTMGR_MOUNT_POINTS)outputBuffer;
  479. mountPoints = output->NumberOfMountPoints;
  480. if ( !mountPoints ) {
  481. return ERROR_INVALID_DATA;
  482. }
  483. byteBuffer = outputBuffer + output->MountPoints[0].UniqueIdOffset;
  484. idSignature = (LPDWORD)byteBuffer;
  485. if ( Signature == *idSignature ) {
  486. NTSTATUS ntStatus;
  487. UNICODE_STRING unicodeString;
  488. OEM_STRING oemString;
  489. DWORD count;
  490. UCHAR driveLetter;
  491. UCHAR devName[ MAX_PATH ];
  492. free( wVolumeName );
  493. free(input);
  494. if ( ARGUMENT_PRESENT(UniqueId) ) {
  495. if ( *IdLength > output->MountPoints[0].UniqueIdLength ) {
  496. *IdLength = output->MountPoints[0].UniqueIdLength;
  497. }
  498. RtlCopyMemory( UniqueId, byteBuffer, *IdLength );
  499. }
  500. if ( ARGUMENT_PRESENT(DriveLetter) ) {
  501. *DriveLetter = 0;
  502. while ( mountPoints-- ) {
  503. byteBuffer = outputBuffer +
  504. output->MountPoints[mountPoints].SymbolicLinkNameOffset;
  505. //
  506. // Covert UNICODE name to OEM string upper case
  507. //
  508. unicodeString.Buffer = (PWCHAR)byteBuffer;
  509. unicodeString.MaximumLength = output->MountPoints[mountPoints].SymbolicLinkNameLength + sizeof(WCHAR);
  510. unicodeString.Length = output->MountPoints[mountPoints].SymbolicLinkNameLength;
  511. oemString.Buffer = devName;
  512. oemString.MaximumLength = sizeof(devName);
  513. ntStatus = RtlUpcaseUnicodeStringToOemString(
  514. &oemString,
  515. &unicodeString,
  516. FALSE );
  517. if ( ntStatus != STATUS_SUCCESS ) {
  518. status = RtlNtStatusToDosError( ntStatus );
  519. return status;
  520. }
  521. devName[oemString.Length] = '\0';
  522. count = sscanf( devName, "\\DOSDEVICES\\%c:", &driveLetter );
  523. if ( count ) {
  524. *DriveLetter = driveLetter;
  525. break;
  526. }
  527. }
  528. }
  529. return ERROR_SUCCESS;
  530. }
  531. }
  532. free(wVolumeName);
  533. free(input);
  534. }
  535. success = FindNextVolume( Handle,
  536. VolumeName,
  537. BufferLength );
  538. if ( !success ) {
  539. status = GetLastError();
  540. }
  541. } while ( status == ERROR_SUCCESS );
  542. return status;
  543. } // FindNextVolumeForSignature
  544. #if 0
  545. DWORD
  546. DisksSetDiskInfo(
  547. IN HKEY RegistryKey,
  548. IN DWORD Signature
  549. )
  550. /*++
  551. Inputs:
  552. Return Value:
  553. A Win32 error code.
  554. --*/
  555. {
  556. DWORD status;
  557. UCHAR driveLetter;
  558. UCHAR volumeName[MAX_PATH];
  559. HANDLE handle;
  560. HANDLE mHandle;
  561. UCHAR uniqueId[MAX_PATH];
  562. UCHAR smashedId[MAX_PATH+1];
  563. DWORD idLength;
  564. DWORD i;
  565. WCHAR indexName[16];
  566. HKEY registryKey;
  567. DWORD disposition;
  568. status = DevfileOpen( &mHandle, MOUNTMGR_DEVICE_NAME );
  569. if ( status != ERROR_SUCCESS ) {
  570. printf( "SetDiskInfo: DevfileOpen failed, status = %u\n", status);
  571. return status;
  572. }
  573. status = ClusterRegDeleteKey( RegistryKey, L"MountMgr" );
  574. if ( (status != ERROR_SUCCESS) && (status != ERROR_FILE_NOT_FOUND) ) {
  575. DevfileClose( mHandle );
  576. printf( "DiskInfo: ClusterRegDeleteKey failed, status = %1!u!\n", status);
  577. return status;
  578. }
  579. status = ClusterRegCreateKey( RegistryKey,
  580. L"MountMgr",
  581. 0,
  582. KEY_READ | KEY_WRITE,
  583. NULL,
  584. &registryKey,
  585. &disposition );
  586. if ( status != ERROR_SUCCESS ) {
  587. DevfileClose( mHandle );
  588. (DiskpLogEvent)(
  589. ResourceHandle,
  590. LOG_ERROR,
  591. L"SetDiskInfo: ClusterRegCreateKey failed, status = %1!u!\n", status);
  592. return status;
  593. }
  594. idLength = MAX_PATH;
  595. status = FindFirstVolumeForSignature( ResourceHandle,
  596. mHandle,
  597. Signature,
  598. volumeName,
  599. MAX_PATH,
  600. &handle,
  601. uniqueId,
  602. &idLength,
  603. &driveLetter );
  604. if ( status != ERROR_SUCCESS ) {
  605. DevfileClose( mHandle );
  606. ClusterRegCloseKey( registryKey );
  607. (DiskpLogEvent)(
  608. ResourceHandle,
  609. LOG_ERROR,
  610. L"SetDiskInfo: FindFirstVolume failed, status = %1!u!\n", status);
  611. return status;
  612. }
  613. i = 0;
  614. while ( status == ERROR_SUCCESS ) {
  615. wsprintfW( indexName, L"%0.5u", i++ );
  616. smashedId[0] = driveLetter;
  617. RtlCopyMemory( &smashedId[1], uniqueId, idLength );
  618. status = ClusterRegSetValue( registryKey,
  619. indexName,
  620. REG_BINARY,
  621. (CONST BYTE *)smashedId,
  622. idLength + 1);
  623. if ( status != ERROR_SUCCESS ) {
  624. //printf("DiskSetDiskInfo, error setting value %s\n", indexName );
  625. }
  626. idLength = MAX_PATH;
  627. status = FindNextVolumeForSignature( mHandle,
  628. Signature,
  629. handle,
  630. volumeName,
  631. MAX_PATH,
  632. uniqueId,
  633. &idLength,
  634. &driveLetter );
  635. }
  636. FindVolumeClose( handle );
  637. DevfileClose( mHandle );
  638. ClusterRegCloseKey( registryKey );
  639. return ERROR_SUCCESS;
  640. } // DisksSetDiskInfo
  641. DWORD
  642. DisksSetMountMgr(
  643. IN HKEY RegistryKey,
  644. IN DWORD Signature
  645. )
  646. /*++
  647. Inputs:
  648. Return Value:
  649. A Win32 error code.
  650. --*/
  651. {
  652. DWORD status;
  653. UCHAR volumeName[MAX_PATH];
  654. LPWSTR wVolumeName;
  655. HANDLE mHandle;
  656. HANDLE handle = NULL;
  657. UCHAR storedId[MAX_PATH+1];
  658. DWORD storedIdSize;
  659. DWORD i;
  660. WCHAR indexName[16];
  661. HKEY registryKey;
  662. DWORD type;
  663. DWORD bufLength;
  664. UCHAR driveLetter[4];
  665. NTSTATUS ntStatus;
  666. status = DevfileOpen( &mHandle, MOUNTMGR_DEVICE_NAME );
  667. if ( status != ERROR_SUCCESS ) {
  668. (DiskpLogEvent)(
  669. ResourceHandle,
  670. LOG_ERROR,
  671. L"SetMountMgr: DevfileOpen failed, status = %1!u!\n", status);
  672. return status;
  673. }
  674. status = ClusterRegOpenKey( RegistryKey,
  675. L"MountMgr",
  676. KEY_READ | KEY_WRITE,
  677. &registryKey );
  678. if ( status != ERROR_SUCCESS ) {
  679. DevfileClose( mHandle );
  680. return status;
  681. (DiskpLogEvent)(
  682. ResourceHandle,
  683. LOG_ERROR,
  684. L"SetMountMgr: ClusterRegOpenKey failed, status = %1!u!\n", status);
  685. }
  686. i = 0;
  687. do {
  688. wsprintfW( indexName, L"%0.5u", i++ );
  689. storedIdSize = MAX_PATH;
  690. status = ClusterRegQueryValue( registryKey,
  691. indexName,
  692. &type,
  693. (PUCHAR)storedId,
  694. &storedIdSize);
  695. (DiskpLogEvent)(
  696. ResourceHandle,
  697. LOG_ERROR,
  698. L"SetMountMgr: ClusterRegQueryValue returned status = %1!u!\n", status);
  699. if ( status != ERROR_SUCCESS ) {
  700. break;
  701. }
  702. storedId[1] = ':';
  703. storedId[2] = '\0';
  704. ntStatus = DisksRemoveDosDevice( storedId );
  705. status = RtlNtStatusToDosError( ntStatus );
  706. (DiskpLogEvent)(
  707. ResourceHandle,
  708. LOG_ERROR,
  709. L"SetMountMgr: RemoveDosDevice for %1!x! returned status = %2!u!\n", *storedId, status);
  710. if ( status == ERROR_FILE_NOT_FOUND ) {
  711. status = ERROR_SUCCESS;
  712. }
  713. } while ( status == ERROR_SUCCESS );
  714. status = FindFirstVolumeForSignature( ResourceHandle,
  715. mHandle,
  716. Signature,
  717. volumeName,
  718. MAX_PATH,
  719. &handle,
  720. NULL,
  721. NULL,
  722. &driveLetter[0] );
  723. if ( status != ERROR_SUCCESS ) {
  724. (DiskpLogEvent)(
  725. ResourceHandle,
  726. LOG_ERROR,
  727. L"SetMountMgr: FindFirstVolume failed for Signature %1!08lx!, status = %2!u!\n", Signature, status);
  728. }
  729. i = 0;
  730. while ( status == ERROR_SUCCESS ) {
  731. wsprintfW( indexName, L"%0.5u", i++ );
  732. storedIdSize = MAX_PATH;
  733. status = ClusterRegQueryValue( registryKey,
  734. indexName,
  735. &type,
  736. (PUCHAR)storedId,
  737. &storedIdSize );
  738. if ( status != ERROR_SUCCESS ) {
  739. break;
  740. }
  741. //
  742. // Remove current drive letter
  743. //
  744. driveLetter[1] = ':';
  745. driveLetter[2] = '\0';
  746. ntStatus = DisksRemoveDosDevice( driveLetter );
  747. status = RtlNtStatusToDosError( ntStatus );
  748. (DiskpLogEvent)(
  749. ResourceHandle,
  750. LOG_ERROR,
  751. L"SetMountMgr: RemoveDosDevice for %1!x! returned status = %2!u!\n", driveLetter[0], status);
  752. bufLength = strlen( volumeName );
  753. wVolumeName = malloc( (bufLength + 1) * sizeof(WCHAR) );
  754. if (!wVolumeName) {
  755. status = ERROR_NOT_ENOUGH_MEMORY;
  756. break;
  757. }
  758. mbstowcs( wVolumeName, volumeName, bufLength + 1 );
  759. storedId[1] = ':';
  760. storedId[2] = '\0';
  761. status = DisksAssignDosDevice( storedId, wVolumeName );
  762. (DiskpLogEvent)(
  763. ResourceHandle,
  764. LOG_ERROR,
  765. L"SetMountMgr: AssignDosDevice for %1!x! (%2!ws!) returned status = %3!u!\n", *storedId, wVolumeName, status);
  766. free( wVolumeName );
  767. if ( status != ERROR_SUCCESS ) {
  768. break;
  769. }
  770. status = FindNextVolumeForSignature( mHandle,
  771. Signature,
  772. handle,
  773. volumeName,
  774. MAX_PATH,
  775. NULL,
  776. NULL,
  777. &driveLetter[0] );
  778. if ( status != ERROR_SUCCESS ) {
  779. (DiskpLogEvent)(
  780. ResourceHandle,
  781. LOG_ERROR,
  782. L"SetMountMgr: FindNextVolume failed, status = %1!u!\n", status);
  783. }
  784. if ( status == ERROR_NO_MORE_FILES ) {
  785. status = ERROR_SUCCESS;
  786. break;
  787. }
  788. }
  789. DevfileClose( mHandle );
  790. ClusterRegCloseKey( registryKey );
  791. if ( handle ) {
  792. FindVolumeClose( handle );
  793. }
  794. return status;
  795. } // DisksSetMountMgr
  796. BOOL
  797. DisksDoesDiskInfoMatch(
  798. IN HKEY RegistryKey,
  799. IN DWORD Signature
  800. )
  801. /*++
  802. Inputs:
  803. Return Value:
  804. A Win32 error code.
  805. --*/
  806. {
  807. DWORD status;
  808. UCHAR driveLetter;
  809. UCHAR volumeName[MAX_PATH];
  810. HANDLE handle;
  811. HANDLE mHandle;
  812. UCHAR uniqueId[MAX_PATH];
  813. UCHAR smashedId[MAX_PATH+1];
  814. UCHAR storedId[MAX_PATH+1];
  815. DWORD idLength;
  816. DWORD storedIdSize;
  817. DWORD i;
  818. WCHAR indexName[16];
  819. HKEY registryKey;
  820. DWORD type;
  821. status = DevfileOpen( &mHandle, MOUNTMGR_DEVICE_NAME );
  822. if ( status != ERROR_SUCCESS ) {
  823. return FALSE;
  824. }
  825. status = ClusterRegOpenKey( RegistryKey,
  826. L"MountMgr",
  827. KEY_READ | KEY_WRITE,
  828. &registryKey );
  829. if ( status != ERROR_SUCCESS ) {
  830. DevfileClose( mHandle );
  831. return FALSE;
  832. }
  833. idLength = MAX_PATH;
  834. status = FindFirstVolumeForSignature( ResourceHandle,
  835. mHandle,
  836. Signature,
  837. volumeName,
  838. MAX_PATH,
  839. &handle,
  840. uniqueId,
  841. &idLength,
  842. &driveLetter );
  843. if ( status != ERROR_SUCCESS ) {
  844. DevfileClose( mHandle );
  845. ClusterRegCloseKey( registryKey );
  846. return FALSE;
  847. }
  848. i = 0;
  849. while ( status == ERROR_SUCCESS ) {
  850. wsprintfW( indexName, L"%0.5u", i++ );
  851. smashedId[0] = driveLetter;
  852. RtlCopyMemory( &smashedId[1], uniqueId, idLength );
  853. storedIdSize = MAX_PATH;
  854. status = ClusterRegQueryValue( registryKey,
  855. indexName,
  856. &type,
  857. (PUCHAR)storedId,
  858. &storedIdSize);
  859. if ( (status != ERROR_SUCCESS) ||
  860. (type != REG_BINARY) ||
  861. (storedIdSize != (idLength+1)) ||
  862. (RtlCompareMemory( smashedId, storedId, idLength ) != idLength) ) {
  863. FindVolumeClose( handle );
  864. DevfileClose( mHandle );
  865. ClusterRegCloseKey( registryKey );
  866. return FALSE;
  867. }
  868. idLength = MAX_PATH;
  869. status = FindNextVolumeForSignature( mHandle,
  870. Signature,
  871. handle,
  872. volumeName,
  873. MAX_PATH,
  874. uniqueId,
  875. &idLength,
  876. &driveLetter );
  877. }
  878. FindVolumeClose( handle );
  879. DevfileClose( mHandle );
  880. ClusterRegCloseKey( registryKey );
  881. if ( status != ERROR_NO_MORE_FILES ) {
  882. return FALSE;
  883. }
  884. return TRUE;
  885. } // DisksDoesDiskInfoMatch
  886. BOOL
  887. DisksIsDiskInfoValid(
  888. IN HKEY RegistryKey,
  889. IN DWORD Signature
  890. )
  891. /*++
  892. Inputs:
  893. Return Value:
  894. A Win32 error code.
  895. --*/
  896. {
  897. DWORD status;
  898. UCHAR volumeName[MAX_PATH];
  899. UCHAR storedId[MAX_PATH+1];
  900. DWORD storedIdSize;
  901. WCHAR indexName[16];
  902. HKEY registryKey;
  903. DWORD i;
  904. DWORD type;
  905. HANDLE handle;
  906. HANDLE mHandle;
  907. status = DevfileOpen( &mHandle, MOUNTMGR_DEVICE_NAME );
  908. if ( status != ERROR_SUCCESS ) {
  909. return FALSE;
  910. }
  911. status = ClusterRegOpenKey( RegistryKey,
  912. L"MountMgr",
  913. KEY_READ | KEY_WRITE,
  914. &registryKey );
  915. if ( status != ERROR_SUCCESS ) {
  916. DevfileClose( mHandle );
  917. return FALSE;
  918. }
  919. status = FindFirstVolumeForSignature( ResourceHandle,
  920. mHandle,
  921. Signature,
  922. volumeName,
  923. MAX_PATH,
  924. &handle,
  925. NULL,
  926. NULL,
  927. NULL );
  928. if ( status != ERROR_SUCCESS ) {
  929. DevfileClose( mHandle );
  930. ClusterRegCloseKey( registryKey );
  931. return TRUE;
  932. }
  933. i = 0;
  934. while ( status == ERROR_SUCCESS ) {
  935. wsprintfW( indexName, L"%0.5u", i++ );
  936. storedIdSize = MAX_PATH;
  937. status = ClusterRegQueryValue( registryKey,
  938. indexName,
  939. &type,
  940. (PUCHAR)storedId,
  941. &storedIdSize);
  942. if ( (status != ERROR_SUCCESS) ||
  943. (type != REG_BINARY) ) {
  944. FindVolumeClose( handle );
  945. DevfileClose( mHandle );
  946. ClusterRegCloseKey( registryKey );
  947. if ( status == ERROR_FILE_NOT_FOUND ) {
  948. return TRUE;
  949. } else {
  950. return FALSE;
  951. }
  952. }
  953. status = FindNextVolumeForSignature( mHandle,
  954. Signature,
  955. handle,
  956. volumeName,
  957. MAX_PATH,
  958. NULL,
  959. NULL,
  960. NULL );
  961. }
  962. FindVolumeClose( handle );
  963. DevfileClose( mHandle );
  964. ClusterRegCloseKey( registryKey );
  965. return TRUE;
  966. } // DisksIsDiskInfoValid
  967. #endif