📄 smpd_mapdrive.c
字号:
/* -*- Mode: C; c-basic-offset:4 ; -*- *//* * (C) 2001 by Argonne National Laboratory. * See COPYRIGHT in top-level directory. */#include "smpd.h"static SMPD_BOOL UnmapDrive(char *pszDrive, char *pszError, int maxerrlength);static SMPD_BOOL MapDrive(char *pszDrive, char *pszShare, char *pszAccount, char *pszPassword, char *pszError, int maxerrlength);typedef struct DriveMapStruct{ int nRefCount; char pszDrive[10]; char pszShare[MAX_PATH]; SMPD_BOOL bUnmap; struct DriveMapStruct *pNext;} DriveMapStruct;DriveMapStruct * allocate_DriveMapStruct(){ DriveMapStruct *p; p = (DriveMapStruct*)malloc(sizeof(DriveMapStruct)); if (p == NULL) return NULL; p->nRefCount = 1; p->pszDrive[0] = '\0'; p->pNext = NULL; p->bUnmap = SMPD_TRUE; return p;}static DriveMapStruct *g_pDriveList = NULL;static SMPD_BOOL AlreadyMapped(char *pszDrive, char *pszShare, SMPD_BOOL *pMatched){ DriveMapStruct *p; if (g_pDriveList == NULL) return SMPD_FALSE; p = g_pDriveList; while (p) { if (pszDrive[0] == p->pszDrive[0]) { if ((stricmp(pszShare, p->pszShare) == 0)) { p->nRefCount++; *pMatched = SMPD_TRUE; } else *pMatched = SMPD_FALSE; return SMPD_TRUE; } p = p->pNext; } return SMPD_FALSE;}static SMPD_BOOL CompareHosts(char *pszHost1, char *pszHost2){ unsigned long ip1, ip2; struct hostent *pH; pH = gethostbyname(pszHost1); if (pH == NULL) return SMPD_FALSE; ip1 = *(unsigned long*)(pH->h_addr_list[0]); pH = gethostbyname(pszHost2); if (pH == NULL) return SMPD_FALSE; ip2 = *(unsigned long*)(pH->h_addr_list[0]); return (ip1 == ip2);}static BOOL EnumerateDisksFunc(LPNETRESOURCE lpnr, DWORD dwScope, DWORD dwType, char *pszDrive, char *pszShare, SMPD_BOOL *pbFound, SMPD_BOOL *pbMatched){ DWORD dwResult, dwResultEnum; HANDLE hEnum; DWORD cbBuffer = 16384; /* 16K is a good size */ DWORD cEntries = (DWORD)-1; /* enumerate all possible entries */ LPNETRESOURCE lpnrLocal; /* pointer to enumerated structures */ DWORD i; dwResult = WNetOpenEnum( dwScope, dwType, 0, /* enumerate all resources */ lpnr, /* NULL first time the function is called */ &hEnum); /* handle to the resource */ if (dwResult != NO_ERROR) return FALSE; lpnrLocal = (LPNETRESOURCE) GlobalAlloc(GPTR, cbBuffer); do { ZeroMemory(lpnrLocal, cbBuffer); dwResultEnum = WNetEnumResource( hEnum, /* resource handle */ &cEntries, /* defined locally as -1 */ lpnrLocal, /* LPNETRESOURCE */ &cbBuffer); /* buffer size */ /* If the call succeeds, loop through the structures. */ if (dwResultEnum == NO_ERROR) { for(i = 0; i < cEntries; i++) { if (lpnrLocal[i].lpLocalName && lpnrLocal[i].lpRemoteName) { if (toupper(*lpnrLocal[i].lpLocalName) == *pszDrive) { *pbFound = SMPD_TRUE; if ((stricmp(lpnrLocal[i].lpRemoteName, pszShare) == 0)) { *pbMatched = SMPD_TRUE; } else { char *pPath1, *pPath2; pPath1 = strstr(&lpnrLocal[i].lpRemoteName[2], "\\"); if (pPath1 != NULL) { pPath1++; /* advance over the \ character */ pPath2 = strstr(&pszShare[2], "\\"); if (pPath2 != NULL) { pPath2++; /* advance over the \ character */ if (stricmp(pPath1, pPath2) == 0) { char pszHost1[50], pszHost2[50]; int nLength1, nLength2; nLength1 = (int)(pPath1 - &lpnrLocal[i].lpRemoteName[2] - 1); nLength2 = (int)(pPath2 - &pszShare[2] - 1); strncpy(pszHost1, &lpnrLocal[i].lpRemoteName[2], nLength1); strncpy(pszHost2, &pszShare[2], nLength2); pszHost1[nLength1] = '\0'; pszHost2[nLength2] = '\0'; if (CompareHosts(pszHost1, pszHost2)) *pbMatched = SMPD_TRUE; } } } } } } /* If the NETRESOURCE structure represents a container resource, */ /* call the EnumerateDisksFunc function recursively. */ if (RESOURCEUSAGE_CONTAINER == (lpnrLocal[i].dwUsage & RESOURCEUSAGE_CONTAINER)) EnumerateDisksFunc(&lpnrLocal[i], dwScope, dwType, pszDrive, pszShare, pbFound, pbMatched); } } else if (dwResultEnum != ERROR_NO_MORE_ITEMS) { break; } } while(dwResultEnum != ERROR_NO_MORE_ITEMS); GlobalFree((HGLOBAL)lpnrLocal); dwResult = WNetCloseEnum(hEnum); if (dwResult != NO_ERROR) return FALSE; return TRUE;}static SMPD_BOOL MatchesExistingMapping(char *pszDrive, char *pszShare){ SMPD_BOOL bFound = SMPD_FALSE; SMPD_BOOL bMatched = SMPD_FALSE; char ch; if (pszDrive == NULL || pszShare == NULL) return SMPD_FALSE; ch = (char)(toupper(*pszDrive)); EnumerateDisksFunc(NULL, RESOURCE_CONNECTED, RESOURCETYPE_DISK, &ch, pszShare, &bFound, &bMatched); if (bMatched) return SMPD_TRUE; EnumerateDisksFunc(NULL, RESOURCE_REMEMBERED, RESOURCETYPE_DISK, &ch, pszShare, &bFound, &bMatched); if (bMatched) return SMPD_TRUE; /* If it was not found, assume that it matches */ return !bFound;}static void RemoveDriveStruct(char *pszDrive){ DriveMapStruct *p, *pTrailer; pTrailer = p = g_pDriveList; while (p) { if (p->pszDrive[0] == pszDrive[0]) { p->nRefCount--; if (p->nRefCount == 0) { if (pTrailer != p) pTrailer->pNext = p->pNext; if (g_pDriveList == p) g_pDriveList = g_pDriveList->pNext; free(p); } return; } if (pTrailer != p) pTrailer = pTrailer->pNext; p = p->pNext; }}#undef FCNAME#define FCNAME "smpd_finalize_drive_maps"void smpd_finalize_drive_maps(){ char err_msg[256]; char temp[MAX_PATH+2]; smpd_enter_fn(FCNAME); while (g_pDriveList) { snprintf(temp, MAX_PATH+2, "%c:%s", g_pDriveList->pszDrive[0], g_pDriveList->pszShare); if (!UnmapDrive(temp, err_msg, 256)) break; } while (g_pDriveList) { RemoveDriveStruct(g_pDriveList->pszDrive); } smpd_exit_fn(FCNAME);}static SMPD_BOOL ParseDriveShareAccountPassword(char *str, char *pszDrive, char *pszShare, char *pszAccount, char *pszPassword){ pszDrive[0] = str[0]; pszDrive[1] = ':'; pszDrive[2] = '\0'; while (*str != '\\') str++; if (strstr(str, ":")) { while (*str != ':') *pszShare++ = *str++; *pszShare = '\0'; str++; if (!strstr(str, ":")) return SMPD_FALSE; while (*str != ':') *pszAccount++ = *str++; *pszAccount = '\0'; str++; strcpy(pszPassword, str); } else { strcpy(pszShare, str); *pszAccount = '\0'; } return SMPD_TRUE;}#ifdef HAVE_WINDOWS_H/* There can be atmost 26 logical drives -- currently limiting to 10*/#define SMPD_LOGICALDRVNUM_MAX 10/* Each drive letter occupies 3 TCHARs -- "A:\" */#define SMPD_LOGICALDRVLEN_MAX 3/* Each drive string is of the form "%s0x0" - 1 delim */#define SMPD_LOGICALDRVDELIM_MAX 1#define SMPD_LOGICALDRVSTR_NODELIM_MAX \ (SMPD_LOGICALDRVNUM_MAX * (SMPD_LOGICALDRVLEN_MAX * sizeof(TCHAR)))#define SMPD_LOGICALDRVSTR_MAX \ (SMPD_LOGICALDRVSTR_NODELIM_MAX + SMPD_LOGICALDRVDELIM_MAX * SMPD_LOGICALDRVNUM_MAX * sizeof(TCHAR))/* Each map string is of the form "%s%s;" - 1 delims */#define SMPD_MAPLISTDELIM_MAX 1/* Network drv name \\compname\share -- is currently limited to 50 TCHARS */#define SMPD_MAPNETWORKDRVSTR_MAX 100/* Map list item = "%s%s;" - A:\\compname\share; */#define SMPD_MAPLISTITEM_MAX \ (SMPD_LOGICALDRVLEN_MAX * sizeof(TCHAR) + SMPD_MAPLISTDELIM_MAX + SMPD_MAPNETWORKDRVSTR_MAX) #define SMPD_MAPLISTSTR_MAX (SMPD_MAPLISTITEM_MAX * SMPD_LOGICALDRVNUM_MAX)#undef FCNAME#define FCNAME "smpd_get_network_drives"int smpd_get_network_drives(char *pMapList, int mapListLen){ DWORD retVal, mapNetworkDrvLen; UINT drvType; LPTSTR pDrv, pNetDrv; /* TODO : Allocate these large arrays in heap */ TCHAR logicalDrvs[SMPD_LOGICALDRVSTR_MAX], mapNetworkDrv[SMPD_MAPNETWORKDRVSTR_MAX]; smpd_enter_fn(FCNAME); if(mapListLen > SMPD_MAPLISTSTR_MAX){ printf("Error: Not enough mem for mapping network drive\n"); smpd_exit_fn(FCNAME); return SMPD_FAIL; } if(retVal = GetLogicalDriveStrings(SMPD_LOGICALDRVSTR_NODELIM_MAX, logicalDrvs)){ /* logicalDrvs = "A:\[0x0]C:\[0x0]X:\[0x0][0x0]" */ pDrv = logicalDrvs; while(*pDrv){ drvType = GetDriveType(pDrv); pNetDrv = pDrv; /* Increment pDrv before any changes to the contents */ pDrv += (_tcslen(pDrv) + 1); switch(drvType){ /* Network mapped drive */ case DRIVE_REMOTE: /* Convert "A:\[0x0]" to "A:[0x0][0x0]" */ pNetDrv[_tcslen(pNetDrv) - 1] = '\0'; mapNetworkDrvLen=SMPD_MAPNETWORKDRVSTR_MAX; if((retVal = WNetGetConnection(pNetDrv, mapNetworkDrv, &mapNetworkDrvLen)) == NO_ERROR){ if(mapNetworkDrvLen <= SMPD_MAPNETWORKDRVSTR_MAX){ MPIU_Snprintf(pMapList, SMPD_MAPLISTITEM_MAX, "%s%s;",pNetDrv, mapNetworkDrv); pMapList += _tcslen(pMapList); }else{ printf("Error: Not enough space for %s = WNetGetConnection(%s, ...) failed\n", mapNetworkDrv, pNetDrv); smpd_exit_fn(FCNAME); return SMPD_FAIL; } }else{ printf("Error: WNetGetConnection(%s, ...) failed\n", pNetDrv); smpd_exit_fn(FCNAME); return SMPD_FAIL; } break; default: break; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -