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

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: }

unix.superglobalmegacorp.com

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