159 lines
3.8 KiB
C
159 lines
3.8 KiB
C
/*
|
|
* DRIVE.C
|
|
*
|
|
*
|
|
* DRIVEARB.DLL - Shared Drive Aribiter for shared disks and libraries
|
|
* - inter-machine sharing client
|
|
* - inter-app sharing service
|
|
*
|
|
* Author: ErvinP
|
|
*
|
|
* (c) 2000 Microsoft Corporation
|
|
*
|
|
*/
|
|
|
|
#include <stdlib.h>
|
|
#include <wtypes.h>
|
|
|
|
#include <dlmhdr.h> // BUGBUG - get a common DLM header from Cluster team
|
|
|
|
#include <drivearb.h>
|
|
#include "internal.h"
|
|
|
|
|
|
/*
|
|
* NewDriveContext
|
|
*
|
|
* Must be called with globalMutex held.
|
|
* Should only be called in the service context, not by a client.
|
|
*
|
|
*/
|
|
driveContext *NewDriveContext(LPSTR driveName)
|
|
{
|
|
driveContext *drive = NULL;
|
|
DWORD driveIndex;
|
|
|
|
/*
|
|
* Find an available drive context
|
|
*
|
|
* BUGBUG - make this more efficient; e.g. use a free list
|
|
*/
|
|
for (driveIndex = 0; driveIndex < g_numDrivesInFileMap; driveIndex++){
|
|
driveContext *d = &g_allDrivesViewPtr[driveIndex];
|
|
if (d->state == DRIVESTATE_NONE){
|
|
drive = d;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (drive){
|
|
char driveMutexName[sizeof(DRIVE_MUTEX_NAME_PREFIX)+8];
|
|
|
|
drive->sig = DRIVEARB_SIG;
|
|
|
|
wsprintf(driveMutexName, "%s%08x", DRIVE_MUTEX_NAME_PREFIX, driveIndex);
|
|
drive->mutex = CreateMutex(NULL, FALSE, (LPSTR)driveMutexName);
|
|
if (drive->mutex){
|
|
char driveEventName[sizeof(DRIVE_EVENT_NAME_PREFIX)+8];
|
|
|
|
wsprintf(driveEventName, "%s%08x", DRIVE_EVENT_NAME_PREFIX, driveIndex);
|
|
drive->event = CreateEvent(NULL, FALSE, FALSE, (LPSTR)driveEventName);
|
|
if (drive->event){
|
|
|
|
drive->state = DRIVESTATE_UNAVAILABLE_LOCALLY;
|
|
|
|
MyStrNCpy(drive->driveName, driveName, MAX_PATH);
|
|
|
|
// DBGMSG("NewDriveContext created drive:", driveIndex);
|
|
// DBGMSG(drive->driveName, 0);
|
|
}
|
|
else {
|
|
CloseHandle(drive->mutex);
|
|
drive = NULL;
|
|
}
|
|
}
|
|
else {
|
|
drive = NULL;
|
|
}
|
|
}
|
|
else {
|
|
/*
|
|
* No more free drive contexts in the current fileMap.
|
|
* So grow the fileMap and try again.
|
|
*/
|
|
BOOL ok = GrowDrivesFileMapping(g_numDrivesInFileMap*2);
|
|
if (ok){
|
|
drive = NewDriveContext(driveName);
|
|
}
|
|
}
|
|
|
|
return drive;
|
|
}
|
|
|
|
|
|
/*
|
|
* FreeDriveContext
|
|
*
|
|
* Must be called with globalMutex held.
|
|
* Should only be called in the service context, not by a client.
|
|
*
|
|
*/
|
|
VOID FreeDriveContext(driveContext *drive)
|
|
{
|
|
CloseHandle(drive->mutex);
|
|
CloseHandle(drive->event);
|
|
drive->state = DRIVESTATE_NONE;
|
|
}
|
|
|
|
|
|
/*
|
|
* GetDriveIndexByName
|
|
*
|
|
* Must be called with globalMutex held.
|
|
*
|
|
* Return drive index if it exists; else return -1.
|
|
*/
|
|
DWORD GetDriveIndexByName(LPSTR driveName)
|
|
{
|
|
HANDLE hDrivesFileMap;
|
|
DWORD driveIndex = -1;
|
|
|
|
/*
|
|
* Create a temporary read-only mapping of the entire drives array
|
|
* so we can look for the drive.
|
|
*/
|
|
hDrivesFileMap = OpenFileMapping(FILE_MAP_READ, FALSE, DRIVES_FILEMAP_NAME);
|
|
if (hDrivesFileMap){
|
|
|
|
driveContext *allDrivesViewPtr = MapViewOfFile(hDrivesFileMap, FILE_MAP_READ, 0, 0, 0);
|
|
if (allDrivesViewPtr){
|
|
DWORD i;
|
|
|
|
for (i = 0; i < g_numDrivesInFileMap; i++){
|
|
driveContext *d = &allDrivesViewPtr[i];
|
|
|
|
if ((d->state != DRIVESTATE_NONE) &&
|
|
MyCompareStringsI(d->driveName, driveName)){
|
|
|
|
driveIndex = i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
UnmapViewOfFile(allDrivesViewPtr);
|
|
}
|
|
else {
|
|
ASSERT(allDrivesViewPtr);
|
|
}
|
|
|
|
CloseHandle(hDrivesFileMap);
|
|
}
|
|
else {
|
|
ASSERT(hDrivesFileMap);
|
|
}
|
|
|
|
ASSERT(driveIndex != -1);
|
|
return driveIndex;
|
|
}
|
|
|