312 lines
8.6 KiB
C
312 lines
8.6 KiB
C
/*++
|
||
|
||
Copyright (c) 1996 Microsoft Corporation
|
||
|
||
Module Name:
|
||
|
||
partiton.c
|
||
|
||
Abstract:
|
||
|
||
Partition scanning routines and assigning Dos Device Letters.
|
||
|
||
Author:
|
||
|
||
Rod Gamache (rodga) 20-Feb-1996
|
||
|
||
Revision History:
|
||
|
||
--*/
|
||
|
||
#include "windows.h"
|
||
#include "winioctl.h"
|
||
#include "ntddscsi.h"
|
||
#include "string.h"
|
||
#include "stdio.h"
|
||
#include "stdlib.h"
|
||
|
||
#include "disksp.h"
|
||
#include "clusdisk.h"
|
||
#include "lm.h"
|
||
#include "lmerr.h"
|
||
|
||
|
||
#define UNICODE 1
|
||
#define ENTRIES_PER_BOOTSECTOR 8
|
||
|
||
|
||
BOOLEAN
|
||
GetAssignedDriveLetter(
|
||
ULONG Signature,
|
||
LARGE_INTEGER StartingOffset,
|
||
LARGE_INTEGER Length,
|
||
PUCHAR DriveLetter,
|
||
PULONG Partition
|
||
);
|
||
|
||
|
||
DWORD
|
||
AssignDriveLetters(
|
||
PDISK_INFO DiskInfo
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine scans the partitions on a specified volume and assigns device
|
||
letters. If the DosDeviceLetter has already been assigned, then everything
|
||
is fine. Otherwise, the 'sticky' device letter from the registry is used.
|
||
An error is returned if there is a partition that does not have any
|
||
registry information or no 'sticky' device letter.
|
||
|
||
Arguments:
|
||
|
||
DiskInfo - The disk information for this partition.
|
||
|
||
Return Value:
|
||
|
||
Win32 Error Status - ERROR_SUCCESS if success.
|
||
|
||
--*/
|
||
|
||
{
|
||
DWORD status;
|
||
DWORD returnLength;
|
||
DWORD diskSignature;
|
||
DWORD driveLayoutSize;
|
||
DWORD partNumber;
|
||
DWORD index;
|
||
PDRIVE_LAYOUT_INFORMATION driveLayout;
|
||
PPARTITION_INFORMATION partInfo;
|
||
WCHAR targetPath[100];
|
||
WCHAR newName[8];
|
||
UCHAR driveLetter;
|
||
BOOL success;
|
||
DWORD partition;
|
||
|
||
driveLayoutSize = sizeof(DRIVE_LAYOUT_INFORMATION) +
|
||
(sizeof(PARTITION_INFORMATION) * MAX_PARTITIONS);
|
||
|
||
driveLayout = LocalAlloc( LMEM_FIXED, driveLayoutSize );
|
||
|
||
ZeroMemory( driveLayout, driveLayoutSize );
|
||
|
||
if ( !driveLayout ) {
|
||
printf( "AssignDriveLetters, failed to allocate drive layout info.\n");
|
||
return(ERROR_OUTOFMEMORY);
|
||
}
|
||
|
||
success = DeviceIoControl( DiskInfo->FileHandle,
|
||
IOCTL_DISK_GET_DRIVE_LAYOUT,
|
||
NULL,
|
||
0,
|
||
driveLayout,
|
||
driveLayoutSize,
|
||
&returnLength,
|
||
FALSE );
|
||
|
||
if ( !success ) {
|
||
printf( "AssignDriveLetters, error getting drive layout, %u.\n",
|
||
status = GetLastError() );
|
||
LocalFree( driveLayout );
|
||
return(status);
|
||
}
|
||
|
||
if ( returnLength < (sizeof(DRIVE_LAYOUT_INFORMATION) +
|
||
(sizeof(PARTITION_INFORMATION) *
|
||
(driveLayout->PartitionCount-1))) ) {
|
||
printf("Found %d partitons, need %u, return size %u.\n",
|
||
driveLayout->PartitionCount, sizeof(DRIVE_LAYOUT_INFORMATION) +
|
||
(sizeof(PARTITION_INFORMATION) * (driveLayout->PartitionCount - 1)), returnLength);
|
||
printf("AssignDriveLetters, error getting drive layout. Zero length returned.\n");
|
||
LocalFree( driveLayout );
|
||
return(ERROR_INSUFFICIENT_BUFFER);
|
||
}
|
||
|
||
//
|
||
// Process all partitions, assigning drive letters.
|
||
//
|
||
|
||
ZeroMemory(DiskInfo->Letters, sizeof(DiskInfo->Letters));
|
||
|
||
for ( index = 0;
|
||
(index < driveLayout->PartitionCount) &&
|
||
(index < ENTRIES_PER_BOOTSECTOR);
|
||
index++ ) {
|
||
|
||
partInfo = &driveLayout->PartitionEntry[index];
|
||
if ( (partInfo->PartitionType == PARTITION_ENTRY_UNUSED) ||
|
||
!partInfo->RecognizedPartition ) {
|
||
printf("AssignDriveLetters, unused partition found, index %u.\n", index);
|
||
continue;
|
||
}
|
||
|
||
partNumber = partInfo->PartitionNumber;
|
||
|
||
if ( partNumber > MAX_PARTITIONS ) {
|
||
printf("AssignDriveLetters, bad partition number %u, index %u.\n",
|
||
partNumber, index);
|
||
break;
|
||
}
|
||
|
||
GetAssignedDriveLetter( driveLayout->Signature,
|
||
partInfo->StartingOffset,
|
||
partInfo->PartitionLength,
|
||
&driveLetter,
|
||
&partition );
|
||
|
||
printf("AssignDriveLetters found letter %c, partition %u, offset %u, length %u.\n",
|
||
driveLetter, partNumber, partInfo->StartingOffset, partInfo->PartitionLength);
|
||
if ( driveLetter != ' ' ) {
|
||
|
||
DiskInfo->Letters[partNumber] = driveLetter;
|
||
swprintf( targetPath,
|
||
L"\\Device\\Harddisk%d\\Partition%d",
|
||
DiskInfo->PhysicalDrive,
|
||
partNumber );
|
||
|
||
newName[0] = (TCHAR)driveLetter;
|
||
newName[1] = (TCHAR)':';
|
||
newName[2] = 0;
|
||
|
||
DefineDosDeviceW( DDD_RAW_TARGET_PATH | DDD_NO_BROADCAST_SYSTEM,
|
||
newName,
|
||
targetPath );
|
||
}
|
||
}
|
||
|
||
LocalFree( driveLayout );
|
||
|
||
return(ERROR_SUCCESS);
|
||
|
||
} // AssignDriveLetters
|
||
|
||
|
||
|
||
DWORD
|
||
RemoveDriveLetters(
|
||
PDISK_INFO DiskInfo
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine scans the partitions on a specified volume and removes device
|
||
letters. If the DosDeviceLetter has already been assigned, then everything
|
||
is fine. Otherwise, the 'sticky' device letter from the registry is used.
|
||
An error is returned if there is a partition that does not have any
|
||
registry information or no 'sticky' device letter.
|
||
|
||
Arguments:
|
||
|
||
DiskInfo - The disk information for this partition.
|
||
|
||
Return Value:
|
||
|
||
Win32 Error Status - ERROR_SUCCESS if success.
|
||
|
||
--*/
|
||
|
||
{
|
||
DWORD status;
|
||
DWORD returnLength;
|
||
DWORD diskSignature;
|
||
DWORD driveLayoutSize;
|
||
DWORD index;
|
||
PDRIVE_LAYOUT_INFORMATION driveLayout;
|
||
PPARTITION_INFORMATION partInfo;
|
||
TCHAR newName[8];
|
||
WCHAR shareName[8];
|
||
UCHAR driveLetter;
|
||
BOOL success;
|
||
DWORD partition;
|
||
|
||
driveLayoutSize = sizeof(DRIVE_LAYOUT_INFORMATION) +
|
||
(sizeof(PARTITION_INFORMATION) * MAX_PARTITIONS);
|
||
|
||
driveLayout = LocalAlloc( LMEM_FIXED, driveLayoutSize );
|
||
|
||
if ( !driveLayout ) {
|
||
printf("RemoveDriveLetters, failed to allocate drive layout info.\n");
|
||
return(ERROR_OUTOFMEMORY);
|
||
}
|
||
|
||
success = DeviceIoControl( DiskInfo->FileHandle,
|
||
IOCTL_DISK_GET_DRIVE_LAYOUT,
|
||
NULL,
|
||
0,
|
||
driveLayout,
|
||
driveLayoutSize,
|
||
&returnLength,
|
||
FALSE );
|
||
|
||
if ( !success ) {
|
||
printf("RemoveDriveLetters, error getting partition information, %u.\n",
|
||
status = GetLastError() );
|
||
LocalFree( driveLayout );
|
||
return(status);
|
||
}
|
||
|
||
if ( returnLength < (sizeof(DRIVE_LAYOUT_INFORMATION) +
|
||
sizeof(PARTITION_INFORMATION)) ) {
|
||
printf("RemoveDriveLetters, error getting partition information. Zero length returned.\n");
|
||
LocalFree( driveLayout );
|
||
return(ERROR_INSUFFICIENT_BUFFER);
|
||
}
|
||
|
||
//
|
||
// Process all partitions, assigning drive letters.
|
||
//
|
||
|
||
for ( index = 0;
|
||
(index < driveLayout->PartitionCount) &&
|
||
(index < ENTRIES_PER_BOOTSECTOR);
|
||
index++ ) {
|
||
|
||
partInfo = &driveLayout->PartitionEntry[index];
|
||
|
||
if ( (partInfo->PartitionType == PARTITION_ENTRY_UNUSED) ||
|
||
!partInfo->RecognizedPartition ) {
|
||
continue;
|
||
}
|
||
|
||
GetAssignedDriveLetter( driveLayout->Signature,
|
||
partInfo->StartingOffset,
|
||
partInfo->PartitionLength,
|
||
&driveLetter,
|
||
&partition );
|
||
|
||
printf("Found letter %c, offset %u, length %u\n",
|
||
driveLetter, partInfo->StartingOffset, partInfo->PartitionLength);
|
||
if ( driveLetter != ' ' ) {
|
||
|
||
newName[0] = (TCHAR)driveLetter;
|
||
newName[1] = (TCHAR)':';
|
||
newName[2] = (TCHAR)0;
|
||
|
||
shareName[0] = (WCHAR)driveLetter;
|
||
shareName[1] = (WCHAR)'$';
|
||
shareName[2] = (WCHAR)0;
|
||
#if 0
|
||
NetShareDel( NULL,
|
||
shareName,
|
||
0 );
|
||
#endif
|
||
success = DefineDosDevice( DDD_REMOVE_DEFINITION | DDD_NO_BROADCAST_SYSTEM,
|
||
newName,
|
||
(LPCTSTR) NULL );
|
||
if ( !success ) {
|
||
printf("RemoveDriveLetters, error removing definition for device %c:.\n",
|
||
driveLetter);
|
||
}
|
||
}
|
||
}
|
||
|
||
LocalFree( driveLayout );
|
||
|
||
return(ERROR_SUCCESS);
|
||
|
||
} // RemoveDriveLetters
|
||
|