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