|
|
1.1.1.3 ! root 1: ! 2: /******************************************************************************\ ! 3: * This is a part of the Microsoft Source Code Samples. ! 4: * Copyright (C) 1993 Microsoft Corporation. ! 5: * All rights reserved. ! 6: * This source code is only intended as a supplement to ! 7: * Microsoft Development Tools and/or WinHelp documentation. ! 8: * See these sources for detailed information regarding the ! 9: * Microsoft samples programs. ! 10: \******************************************************************************/ ! 11: 1.1 root 12: /**************************************************************************** 13: * 14: * PROGRAM: Enumdrv.C 15: * 16: * PURPOSE: Determines all drives in the system, both local and remote, 17: * and their file system type 18: * 19: ****************************************************************************/ 1.1.1.2 root 20: #define STRICT 1.1 root 21: #include <windows.h> 22: #include "globals.h" 23: #include "filer.h" 24: #include "enumdrv.h" 25: 26: extern HANDLE ghHeap; // Handle to global heap, declared in FILER.C 27: extern CRITICAL_SECTION gHeapCS; // Global heap critical section var. 28: extern CRITICAL_SECTION gDrvCS; // Drive list critical section var. 29: extern LPDINFO glpDrives; 30: 31: /**************************************************************************** 32: * 1.1.1.3 ! root 33: * FUNCTION: CheckRM(LPTSTR) 1.1 root 34: * 35: * PURPOSE: Verifies that a removeable media drive contains a disk 36: * 37: * COMMENTS: 38: * 39: * This function is called each time a drive type is determined to be 40: * removeable (DRIVE_REMOVEABLE). An attempt is made to open a 41: * file in the root directory of the drive. If the attempt succeeds, 42: * then media is present in the drive and subsequent calls to the 43: * drive can be safely made. If the call fails, then there is no media 44: * present in the drive and no attempts should be made to access this 45: * drive. The Error Mode is temporarily set to 1 to allow failures 46: * to immediately return to the calling program. This eliminates 47: * unwanted dialog boxes that prompt for disks to be placed in the 48: * drive. 49: * 1.1.1.3 ! root 50: * INPUT: szDriveName - removeable media drive name (ex - "a:") 1.1 root 51: * 52: * OUTPUT: Returns TRUE if media present 53: * FALSE if media is not present 54: * 55: ****************************************************************************/ 56: 1.1.1.3 ! root 57: BOOL CheckRM( LPTSTR lpszDriveName ) 1.1 root 58: { 1.1.1.3 ! root 59: TCHAR szFileName[DIRECTORY_STRING_SIZE]; ! 60: DWORD dwHold; ! 61: ! 62: SetErrorMode( SEM_FAILCRITICALERRORS ); ! 63: ! 64: lstrcpy( szFileName, lpszDriveName ); ! 65: lstrcat( szFileName, TEXT(".") ); ! 66: ! 67: dwHold = GetFileAttributes( szFileName ); ! 68: ! 69: SetErrorMode( 0 ); ! 70: ! 71: // If no error, media must be in drive. ! 72: if( dwHold != 0xFFFFFFFF ){ ! 73: return(TRUE); ! 74: } ! 75: else{ ! 76: dwHold = GetLastError(); ! 77: if( dwHold != ERROR_NOT_READY ) ! 78: ErrorMsg(TEXT("CheckRM: Get Removable Media Info Failure.")); ! 79: ! 80: return(FALSE); ! 81: } ! 82: 1.1 root 83: } 84: 85: 86: /**************************************************************************** 87: * 88: * FUNCTION: DWORD EnumDrives(*LPDINFO) 89: * 90: * PURPOSE: Enumerates available drives, and information on them. If the 91: * DINFO structure passed in is NULL, it creates a linked list 92: * of DINFO structures, reporting information on each available 93: * drive. If DINFO points to an existing structure, the list 94: * is updated. 95: * 96: * COMMENTS: 97: * The number of available drives is first determined by a call to 98: * GetLogicalDrives. This provides a bit mask of all logical drives. 99: * 100: * For each logical drive, a call is made to GetDriveType to determine 101: * the drive type. If the logical drive is not in the bit mask that 102: * was created with the GetLogicalDrives call, then this drive is 103: * bypassed. 104: * 1.1.1.3 ! root 105: * GetVolumeInformation is used to determine the file syste for the ! 106: * logical drive. If the drive type is removable, a check must be made ! 107: * to see if the drive contains a disk. If the remote drive contains a ! 108: * disk, then it is safe to proceed with the GetVolumeInformation call. 1.1 root 109: * 110: * INPUT: LPDINFO dINfo: A pointer to a DRVINFO Structure. 111: * 112: * OUTPUT: Returns the number of DINFO structures in the linked 113: * list pointed to by dInfo. Value is negative if error. 114: * 1.1.1.3 ! root 115: \****************************************************************************/ 1.1 root 116: 117: void EnumDrives(LPDINFO *lplpRoot) 118: { 119: DWORD dwDriveMask; 120: DWORD dwCount; 1.1.1.3 ! root 121: LPTSTR lpszRootPathName=TEXT("?:\\"); 1.1 root 122: 1.1.1.3 ! root 123: static LPTSTR lpDriveStrings = NULL; ! 124: LPTSTR lpParse; 1.1 root 125: 126: LPDINFO lpDInfo, // new node ptr 127: lpHold, // list walking ptrs 128: lpBack, 129: lpRoot = *lplpRoot; // root ptr 130: 131: 132: EnterCriticalSection(&gDrvCS); 133: 134: // 135: // Free old drive strings; 136: // With a buffer size of 0, the first call returns the size of buffer needed. 137: // 138: if(lpDriveStrings != NULL){ 139: EnterCriticalSection(&gHeapCS); 1.1.1.3 ! root 140: HeapFree( ghHeap, 0, lpDriveStrings); 1.1 root 141: LeaveCriticalSection(&gHeapCS); 142: } 143: 144: dwCount=GetLogicalDriveStrings( 0, lpDriveStrings); 145: if( !dwCount ){ 146: LeaveCriticalSection(&gDrvCS); 1.1.1.3 ! root 147: ErrorMsg(TEXT("EnumDrives: Get Drive Strings error")); 1.1 root 148: ExitThread((DWORD)-1); 149: } 150: 151: EnterCriticalSection(&gHeapCS); 1.1.1.3 ! root 152: // allocate memory, +1 for trailing NULL ! 153: lpDriveStrings = (LPTSTR)HeapAlloc( ghHeap, 0, (dwCount + 1) * sizeof(TCHAR) ); 1.1 root 154: LeaveCriticalSection(&gHeapCS); 155: 156: if( lpDriveStrings == NULL){ 157: LeaveCriticalSection(&gDrvCS); 1.1.1.3 ! root 158: ErrorMsg(TEXT("EnumDrives: Allocation error")); 1.1 root 159: ExitThread((DWORD)-2); 160: } 161: 1.1.1.2 root 162: if(dwCount < GetLogicalDriveStrings( dwCount, lpDriveStrings) ){ 1.1 root 163: LeaveCriticalSection(&gDrvCS); 1.1.1.3 ! root 164: ErrorMsg(TEXT("EnumDrives: Drive String size Changed!")); 1.1 root 165: ExitThread((DWORD)-3); 166: } 167: lpParse = lpDriveStrings; 168: 169: dwDriveMask=GetLogicalDrives(); 170: 171: // 172: // walk list, inserting, deleting, & updating nodes as necessary 173: // 174: dwCount = 0; 175: lpHold = lpBack = lpRoot; 176: 1.1.1.3 ! root 177: for (*lpszRootPathName=TEXT('a');*lpszRootPathName<=TEXT('z');(*lpszRootPathName)++){ 1.1 root 178: if (dwDriveMask & 1){ // drive exists. Insert or update. 179: 180: dwCount++; 181: 182: // 183: // if lpHold (the list walking ptr) is NULL, or the drive that exists 184: // does not already have a node in the list, allocate a node. 185: // 186: if( !lpHold || lpHold->DriveLetter > *lpszRootPathName ){ 187: // 188: // Allocating memory for DRVINFO node 189: // 190: EnterCriticalSection(&gHeapCS); 1.1.1.3 ! root 191: lpDInfo = (LPDINFO) HeapAlloc( ghHeap, 0, (DWORD)sizeof(DRVINFO) ); 1.1 root 192: LeaveCriticalSection(&gHeapCS); 193: if( lpDInfo == NULL){ 194: LeaveCriticalSection(&gDrvCS); 1.1.1.3 ! root 195: ErrorMsg(TEXT("EnumDrives: DRVINFO Allocation error")); 1.1 root 196: ExitThread((DWORD)-4); 197: } 198: 199: // 200: // insert new node into list 201: // 202: if( lpHold == lpRoot ){ 203: lpDInfo->next = lpRoot; 204: lpRoot = lpDInfo; 205: } 206: else{ 207: lpDInfo->next = lpBack->next; 208: lpBack->next = lpDInfo; 209: } 210: 211: lpBack = lpDInfo; 212: lpHold = lpDInfo->next; 213: 214: lpDInfo->DriveLetter = *lpszRootPathName; 215: } 216: else{ 217: if( lpBack != lpHold ) 218: lpBack = lpBack->next; 219: lpHold = lpHold->next; 220: } 221: 222: lpBack->DriveType = GetDriveType(lpszRootPathName); 1.1.1.3 ! root 223: if( lpBack->DriveType == DRIVE_REMOVABLE || ! 224: lpBack->DriveType == DRIVE_CDROM ) ! 225: if( CheckRM(lpszRootPathName ) ) ! 226: if( !GetVolumeInformation(lpszRootPathName,NULL,0,NULL,NULL,NULL, ! 227: (LPTSTR)lpBack->FileSystem, ! 228: (DWORD)FILE_SYSTEM_STRING_SIZE) ) ! 229: lstrcpy(lpBack->FileSystem, TEXT("UNKNOWN")); ! 230: else; ! 231: else // no removable media ! 232: lstrcpy(lpBack->FileSystem, TEXT("UNKNOWN")); ! 233: else // not removable ! 234: if( !GetVolumeInformation(lpszRootPathName,NULL,0,NULL,NULL,NULL, ! 235: (LPTSTR)lpBack->FileSystem, ! 236: (DWORD)FILE_SYSTEM_STRING_SIZE) ) ! 237: lstrcpy(lpBack->FileSystem, TEXT("UNKNOWN")); 1.1 root 238: else; 239: 240: lpBack->DriveName = lpParse; 1.1.1.3 ! root 241: lpParse += lstrlen(lpParse)+1; 1.1 root 242: } 243: else{ // drive does not exist. 244: if( lpHold ) // if node exists, delete it. 245: if( lpHold->DriveLetter == *lpszRootPathName ){ 246: if( lpHold == lpRoot ) 247: lpRoot = lpBack = lpHold->next; 248: else 249: lpBack->next = lpHold->next; 250: 251: EnterCriticalSection(&gHeapCS); 1.1.1.3 ! root 252: HeapFree(ghHeap, 0, (LPVOID)lpHold); 1.1 root 253: LeaveCriticalSection(&gHeapCS); 254: 255: lpHold = lpBack->next; 256: } 257: } 258: dwDriveMask >>= 1; 259: 260: } // end for 261: 262: *lplpRoot = lpRoot; 263: 264: LeaveCriticalSection(&gDrvCS); 265: 266: ExitThread(dwCount); 267: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.