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

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

unix.superglobalmegacorp.com

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