home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / winbase / security / crypto / cfiler / enumdrv.c < prev    next >
C/C++ Source or Header  |  1997-10-08  |  7KB  |  221 lines

  1.  
  2. /******************************************************************************\
  3. *       This is a part of the Microsoft Source Code Samples. 
  4. *       Copyright 1996-1997 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.  
  12. //    PROGRAM: ENUMDRV.C
  13. //
  14. //    PURPOSE: Determines all drives in the system, both local and remote,
  15. //             and their file system type
  16. //
  17.  
  18. #define  STRICT
  19.  
  20. #include "cfiler.h"
  21.  
  22. LPTSTR         lpDriveStrings = NULL;
  23. extern CRITICAL_SECTION gDrvCS;  // Drive list critical section var.
  24. extern LPDINFO          glpDrives;
  25.  
  26. /********************************************************************************\
  27. *    FUNCTION: CheckRM(LPTSTR)
  28. *
  29. *    PURPOSE: Verifies that a removeable media drive contains a disk
  30. *
  31. *    COMMENTS:
  32. *
  33. *        This function is called each time a drive type is determined to be
  34. *        removeable (DRIVE_REMOVEABLE).  An attempt is made to open a
  35. *        file in the root directory of the drive.  If the attempt succeeds,
  36. *        then media is present in the drive and subsequent calls to the
  37. *        drive can be safely made.  If the call fails, then there is no media
  38. *        present in the drive and no attempts should be made to access this
  39. *        drive.  The Error Mode is temporarily set to 1 to allow failures
  40. *        to immediately return to the calling program.  This eliminates
  41. *        unwanted dialog boxes that prompt for disks to be placed in the
  42. *        drive.
  43. *
  44. *    INPUT: szDriveName - removeable media drive name (ex - "a:")
  45. *
  46. *    OUTPUT: Returns TRUE if media present
  47. *                    FALSE if media is not present
  48. \*********************************************************************************/
  49.  
  50. BOOL CheckRM( LPTSTR lpszDriveName )
  51. {
  52.     TCHAR    szFileName[DIRECTORY_STRING_SIZE];
  53.     DWORD    dwHold;
  54.  
  55.     SetErrorMode( SEM_FAILCRITICALERRORS );
  56.  
  57.     lstrcpy( szFileName, lpszDriveName );
  58.     lstrcat( szFileName, TEXT(".") );
  59.  
  60.     dwHold = GetFileAttributes( szFileName );
  61.  
  62.     SetErrorMode( 0 );
  63.  
  64.     //  If no error, media must be in drive.
  65.     if( dwHold != 0xFFFFFFFF ){
  66.         return(TRUE);
  67.     }
  68.     else{
  69.         dwHold = GetLastError();
  70.         if( dwHold != ERROR_NOT_READY )
  71.             ErrorMsg(TEXT("CheckRM: Get Removable Media Info Failure."));
  72.  
  73.         return(FALSE);
  74.     }
  75.  
  76. }
  77.  
  78. /*********************************************************************************\
  79. *    FUNCTION: DWORD EnumDrives(*LPDINFO)
  80. *
  81. *    PURPOSE: Enumerates available drives, and information on them. If the
  82. *               DINFO structure passed in is NULL, it creates a linked list
  83. *               of DINFO structures, reporting information on each available
  84. *              drive.  If DINFO points to an existing structure, the list
  85. *              is updated.
  86. *
  87. *   COMMENTS:
  88. *       The number of available drives is first determined by a call to
  89. *       GetLogicalDrives.  This provides a bit mask of all logical drives.
  90. *
  91. *       For each logical drive, a call is made to GetDriveType to determine
  92. *       the drive type.  If the logical drive is not in the bit mask that
  93. *       was created with the GetLogicalDrives call, then this drive is
  94. *       bypassed.
  95. *
  96. *   INPUT:  LPDINFO dINfo: A pointer to a DRVINFO Structure.
  97. *
  98. *   OUTPUT: Returns the number of DINFO structures in the linked
  99. *           list pointed to by dInfo.  Value is negative if error.
  100. \**********************************************************************************/
  101.  
  102. void EnumDrives(LPDINFO *lplpRoot)
  103. {
  104.   DWORD         dwDriveMask;
  105.   DWORD         dwCount;
  106.   LPTSTR        lpszRootPathName=TEXT("?:\\");
  107.   
  108.   LPTSTR        lpParse;
  109.  
  110.   LPDINFO       lpDInfo = (LPDINFO)0,                // new node ptr
  111.                 lpHold = (LPDINFO)0,                 // list walking ptrs
  112.                 lpBack = (LPDINFO)0,
  113.                 lpRoot = *lplpRoot;     // root ptr
  114.  
  115.  
  116.   EnterCriticalSection(&gDrvCS);
  117.  
  118.   dwCount=GetLogicalDriveStrings( 0, lpDriveStrings);
  119.   if( !dwCount ){
  120.     LeaveCriticalSection(&gDrvCS);
  121.     ErrorMsg(TEXT("EnumDrives: Get Drive Strings error"));
  122.     ExitThread((DWORD)-1);
  123.   }
  124.  
  125.   // allocate memory, +1 for trailing NULL
  126.   lpDriveStrings = (LPTSTR)malloc((dwCount + 1) * sizeof(TCHAR));
  127.  
  128.   if( lpDriveStrings == NULL){
  129.       LeaveCriticalSection(&gDrvCS);
  130.       ErrorMsg(TEXT("EnumDrives: Allocation error"));
  131.       ExitThread((DWORD)-2);
  132.   }
  133.  
  134.   if(dwCount < GetLogicalDriveStrings( dwCount, lpDriveStrings) ){
  135.       LeaveCriticalSection(&gDrvCS);
  136.       ErrorMsg(TEXT("EnumDrives: Drive String size Changed!"));
  137.       ExitThread((DWORD)-3);
  138.   }
  139.   lpParse = lpDriveStrings;
  140.  
  141.   dwDriveMask=GetLogicalDrives();
  142.  
  143.   //
  144.   // walk list, inserting, deleting, & updating nodes as necessary
  145.   //
  146.   dwCount = 0;
  147.   lpHold = lpBack = lpRoot;
  148.  
  149.   for (*lpszRootPathName=TEXT('a');*lpszRootPathName<=TEXT('z');(*lpszRootPathName)++){
  150.     if (dwDriveMask & 1){   // drive exists. Insert or update.
  151.  
  152.       dwCount++;
  153.  
  154.       //
  155.       // if lpHold (the list walking ptr) is NULL, or the drive that exists
  156.       //  does not already have a node in the list, allocate a node.
  157.       //
  158.       if( !lpHold || lpHold->DriveLetter > *lpszRootPathName ){
  159.         //
  160.         // Allocating memory for DRVINFO node
  161.         //
  162.         lpDInfo = (LPDINFO) malloc((DWORD)sizeof(DRVINFO));
  163.       
  164.         if( lpDInfo == NULL){
  165.           LeaveCriticalSection(&gDrvCS);
  166.           ErrorMsg(TEXT("EnumDrives: DRVINFO Allocation error"));
  167.           ExitThread((DWORD)-4);
  168.         }
  169.  
  170.         //
  171.         // insert new node into list
  172.         //
  173.         if( lpHold == lpRoot ){
  174.           lpDInfo->next = lpRoot;
  175.           lpRoot = lpDInfo;
  176.         }
  177.         else{
  178.           lpDInfo->next = lpBack->next;
  179.           lpBack->next = lpDInfo;
  180.         }
  181.  
  182.         lpBack = lpDInfo;
  183.         lpHold = lpDInfo->next;
  184.  
  185.         lpDInfo->DriveLetter = *lpszRootPathName;
  186.       }
  187.       else{
  188.         if( lpBack != lpHold )
  189.           lpBack = lpBack->next;
  190.         lpHold = lpHold->next;
  191.       }
  192.  
  193.       lpBack->DriveType = GetDriveType(lpszRootPathName);
  194.      
  195.       lpBack->DriveName = lpParse;
  196.       lpParse += lstrlen(lpParse)+1;
  197.     }
  198.     else{               // drive does not exist.
  199.       if( lpHold )      //   if node exists, delete it.
  200.         if( lpHold->DriveLetter == *lpszRootPathName ){
  201.           if( lpHold == lpRoot )
  202.             lpRoot = lpBack = lpHold->next;
  203.           else
  204.             lpBack->next = lpHold->next;
  205.  
  206.           free((LPVOID)lpHold);
  207.  
  208.           lpHold = lpBack->next;
  209.         }
  210.     }
  211.     dwDriveMask >>= 1;
  212.   
  213.   } // end for
  214.  
  215.   *lplpRoot = lpRoot;
  216.   
  217.   LeaveCriticalSection(&gDrvCS);
  218.    
  219.   ExitThread(dwCount);
  220. }
  221.