Annotation of mstools/samples/filer/enumdrv.c, revision 1.1.1.2

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.