2 * Copyright 2000, International Business Machines Corporation and others.
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
11 #include <afs/param.h>
14 #include <afs/fs_utils.h>
19 #include <WINNT/TaLocale.h>
26 #include <lanahelper.h>
28 extern void Config_GetLanAdapter (ULONG *pnLanAdapter);
31 * REGISTRY ___________________________________________________________________
35 #undef AFSConfigKeyName
36 const TCHAR sAFSConfigKeyName[] = TEXT("SYSTEM\\CurrentControlSet\\Services\\TransarcAFSDaemon\\Parameters");
40 * PROFILE SECTIONS ___________________________________________________________
44 #define cREALLOC_SUBMOUNTS 4
46 static TCHAR cszINIFILE[] = TEXT("afsdsbmt.ini");
47 static TCHAR cszSECTION_SUBMOUNTS[] = TEXT("AFS Submounts");
48 static TCHAR cszSECTION_MAPPINGS[] = TEXT("AFS Mappings");
49 static TCHAR cszSECTION_ACTIVE[] = TEXT("AFS Active");
51 static TCHAR cszAUTOSUBMOUNT[] = TEXT("Auto");
52 static TCHAR cszLANMANDEVICE[] = TEXT("\\Device\\LanmanRedirector\\");
56 * STRINGS ____________________________________________________________________
60 static LPTSTR AllocateStringMemory (size_t cch)
62 LPTSTR psz = (LPTSTR)Allocate (sizeof(TCHAR) * (cch+1));
63 memset (psz, 0x00, sizeof(TCHAR) * (cch+1));
67 static void FreeStringMemory (LPTSTR pszString)
72 static int lstrncmpi (LPCTSTR pszA, LPCTSTR pszB, size_t cch)
76 return (!pszB) - (!pszA); // A,!B:1, !A,B:-1, !A,!B:0
79 for ( ; cch > 0; cch--, pszA = CharNext(pszA), pszB = CharNext(pszB))
81 TCHAR chA = toupper( *pszA );
82 TCHAR chB = toupper( *pszB );
85 return (!chB) - (!chA); // A,!B:1, !A,B:-1, !A,!B:0
88 return (int)(chA) - (int)(chB); // -1:A<B, 0:A==B, 1:A>B
91 return 0; // no differences before told to stop comparing, so A==B
96 * REALLOC ____________________________________________________________________
101 #define REALLOC(_a,_c,_r,_i) DriveMapReallocFunction ((LPVOID*)&_a,sizeof(*_a),&_c,_r,_i)
102 BOOL DriveMapReallocFunction (LPVOID *ppTarget, size_t cbElement, size_t *pcTarget, size_t cReq, size_t cInc)
107 if (cReq <= *pcTarget)
110 if ((cNew = cInc * ((cReq + cInc-1) / cInc)) <= 0)
113 if ((pNew = Allocate (cbElement * cNew)) == NULL)
115 memset (pNew, 0x00, cbElement * cNew);
119 memcpy (pNew, *ppTarget, cbElement * (*pcTarget));
131 * WINDOWS NT STUFF ___________________________________________________________
135 static BOOL IsWindowsNT (void)
137 static BOOL fChecked = FALSE;
138 static BOOL fIsWinNT = FALSE;
144 OSVERSIONINFO Version;
145 memset (&Version, 0x00, sizeof(Version));
146 Version.dwOSVersionInfoSize = sizeof(Version);
148 if (GetVersionEx (&Version))
150 if (Version.dwPlatformId == VER_PLATFORM_WIN32_NT)
158 /* Check if the OS is Windows 2000 or higher.
160 BOOL IsWindows2000 (void)
162 static BOOL fChecked = FALSE;
163 static BOOL fIsWin2K = FALSE;
169 OSVERSIONINFO Version;
170 memset (&Version, 0x00, sizeof(Version));
171 Version.dwOSVersionInfoSize = sizeof(Version);
173 if (GetVersionEx (&Version))
175 if (Version.dwPlatformId == VER_PLATFORM_WIN32_NT &&
176 Version.dwMajorVersion >= 5)
185 * GENERAL ____________________________________________________________________
189 void GetClientNetbiosName (LPTSTR pszName)
191 *pszName = TEXT('\0');
192 lana_GetNetbiosName(pszName, LANA_NETBIOS_NAME_FULL);
196 BOOL SubmountToPath (PDRIVEMAPLIST pList, LPTSTR pszPath, LPTSTR pszSubmount, BOOL fMarkInUse)
198 // We can't do this translation unless we're under Windows NT.
203 // \\computer-afs\all always maps to "/afs"
205 if (!lstrcmpi (pszSubmount, TEXT("all")))
207 lstrcpy (pszPath, cm_slash_mount_root);
211 // Otherwise, look up our list of submounts.
213 for (size_t ii = 0; ii < pList->cSubmounts; ++ii)
215 if (!lstrcmpi (pList->aSubmounts[ii].szSubmount, pszSubmount))
218 pList->aSubmounts[ii].fInUse = TRUE;
219 AdjustAfsPath (pszPath, pList->aSubmounts[ii].szMapping, TRUE, TRUE);
228 BOOL IsValidSubmountName (LPTSTR pszSubmount)
232 if (lstrlen (pszSubmount) > 12)
235 for ( ; *pszSubmount; ++pszSubmount)
237 if (!isprint(*pszSubmount))
239 if (*pszSubmount == TEXT(' '))
241 if (*pszSubmount == TEXT('\t'))
250 * PIOCTL SUPPORT _____________________________________________________________
256 #include "../afsd/fs_utils.h"
258 #define __CM_CONFIG_INTERFACES_ONLY__
259 #include "../afsd/cm_config.h"
261 #define __CM_IOCTL_INTERFACES_ONLY__
262 #include "../afsd/cm_ioctl.h"
266 #define PIOCTL_MAXSIZE 2048
269 BOOL fCanIssuePIOCTL (void)
273 TCHAR szGateway[ 256 ] = TEXT("");
274 GetClientNetbiosName (szGateway);
275 return (szGateway[0]) ? TRUE : FALSE;
278 SERVICE_STATUS Status;
279 memset (&Status, 0x00, sizeof(Status));
280 Status.dwCurrentState = SERVICE_STOPPED;
283 if ((hManager = OpenSCManager (NULL, NULL, GENERIC_READ)) != NULL)
286 if ((hService = OpenService (hManager, TEXT("TransarcAFSDaemon"), GENERIC_READ)) != NULL)
288 QueryServiceStatus (hService, &Status);
289 CloseServiceHandle (hService);
292 CloseServiceHandle (hManager);
295 return (Status.dwCurrentState == SERVICE_RUNNING) ? TRUE : FALSE;
300 * QUERYDRIVEMAPLIST __________________________________________________________
304 void QueryDriveMapList_ReadSubmounts (PDRIVEMAPLIST pList)
308 size_t cchLHS = 1024;
309 LPTSTR mszLHS = AllocateStringMemory (cchLHS);
311 for (int iRetry = 0; iRetry < 5; ++iRetry)
313 DWORD rc = GetPrivateProfileString (cszSECTION_SUBMOUNTS, NULL, TEXT(""), mszLHS, cchLHS, cszINIFILE);
314 if ((rc != cchLHS-1) && (rc != cchLHS-2))
317 FreeStringMemory (mszLHS);
319 mszLHS = AllocateStringMemory (cchLHS);
322 for (LPTSTR psz = mszLHS; psz && *psz; psz += 1+lstrlen(psz))
325 memset (&Submount, 0x00, sizeof(SUBMOUNT));
326 lstrcpy (Submount.szSubmount, psz);
328 TCHAR szMapping[ MAX_PATH ] = TEXT("");
329 GetPrivateProfileString (cszSECTION_SUBMOUNTS, Submount.szSubmount, TEXT(""), szMapping, MAX_PATH, cszINIFILE);
330 if (szMapping[0] != TEXT('\0'))
332 AdjustAfsPath (Submount.szMapping, szMapping, FALSE, TRUE);
334 for (size_t ii = 0; ii < pList->cSubmounts; ++ii)
336 if (!pList->aSubmounts[ii].szSubmount[0])
339 if (REALLOC (pList->aSubmounts, pList->cSubmounts, 1+ii, cREALLOC_SUBMOUNTS))
341 memcpy (&pList->aSubmounts[ii], &Submount, sizeof(SUBMOUNT));
346 FreeStringMemory (mszLHS);
351 void QueryDriveMapList_ReadMappings (PDRIVEMAPLIST pList)
353 size_t cchLHS = 1024;
354 LPTSTR mszLHS = AllocateStringMemory (cchLHS);
356 for (int iRetry = 0; iRetry < 5; ++iRetry)
358 DWORD rc = GetPrivateProfileString (cszSECTION_MAPPINGS, NULL, TEXT(""), mszLHS, cchLHS, cszINIFILE);
359 if ((rc != cchLHS-1) && (rc != cchLHS-2))
362 FreeStringMemory (mszLHS);
364 mszLHS = AllocateStringMemory (cchLHS);
367 for (LPTSTR psz = mszLHS; psz && *psz; psz += 1+lstrlen(psz))
370 memset (&DriveMap, 0x00, sizeof(DRIVEMAP));
371 DriveMap.chDrive = toupper(*psz);
372 DriveMap.fPersistent = TRUE;
373 if ((DriveMap.chDrive < chDRIVE_A) || (DriveMap.chDrive > chDRIVE_Z))
376 TCHAR szMapping[ MAX_PATH ] = TEXT("");
377 GetPrivateProfileString (cszSECTION_MAPPINGS, psz, TEXT(""), szMapping, MAX_PATH, cszINIFILE);
378 if (szMapping[0] != TEXT('\0'))
380 AdjustAfsPath (DriveMap.szMapping, szMapping, TRUE, TRUE);
381 if (DriveMap.szMapping[ lstrlen(DriveMap.szMapping)-1 ] == TEXT('*'))
383 DriveMap.fPersistent = FALSE;
384 DriveMap.szMapping[ lstrlen(DriveMap.szMapping)-1 ] = TEXT('\0');
386 size_t iDrive = DriveMap.chDrive - chDRIVE_A;
387 memcpy (&pList->aDriveMap[ iDrive ], &DriveMap, sizeof(DRIVEMAP));
391 FreeStringMemory (mszLHS);
394 BOOL ForceMapActive (TCHAR chDrive)
399 szDrive[0] = chDrive;
402 GetPrivateProfileString (cszSECTION_ACTIVE, szDrive, TEXT("0"), szActive, sizeof(szActive), cszINIFILE);
404 if ( !lstrcmp(szActive,"1") || !lstrcmpi(szActive,"true") || !lstrcmpi(szActive,"on") || !lstrcmpi(szActive,"yes") )
410 void WriteActiveMap (TCHAR chDrive, BOOL on)
414 szDrive[0] = chDrive;
417 WritePrivateProfileString (cszSECTION_ACTIVE, szDrive, on ? "1" : "0", cszINIFILE);
420 void QueryDriveMapList_WriteMappings (PDRIVEMAPLIST pList)
422 WriteDriveMappings (pList);
426 void WriteDriveMappings (PDRIVEMAPLIST pList)
428 WritePrivateProfileString (cszSECTION_MAPPINGS, NULL, NULL, cszINIFILE);
430 for (size_t iDrive = 0; iDrive < 26; ++iDrive)
432 if (pList->aDriveMap[iDrive].szMapping[0] != TEXT('\0'))
434 TCHAR szLHS[] = TEXT("*");
435 szLHS[0] = pList->aDriveMap[iDrive].chDrive;
437 TCHAR szRHS[MAX_PATH];
438 AdjustAfsPath (szRHS, pList->aDriveMap[iDrive].szMapping, TRUE, TRUE);
439 if (!pList->aDriveMap[iDrive].fPersistent)
440 lstrcat (szRHS, TEXT("*"));
442 WritePrivateProfileString (cszSECTION_MAPPINGS, szLHS, szRHS, cszINIFILE);
447 BOOL DriveIsGlobalAfsDrive(TCHAR chDrive)
449 TCHAR szKeyName[128];
450 TCHAR szValueName[128];
454 _stprintf(szKeyName, TEXT("%s\\GlobalAutoMapper"), sAFSConfigKeyName);
456 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, szKeyName, 0, KEY_QUERY_VALUE, &hKey) != ERROR_SUCCESS)
459 _stprintf(szValueName, TEXT("%c:"), chDrive);
461 DWORD dwSize = sizeof(szValue);
462 BOOL bIsGlobal = (RegQueryValueEx (hKey, szValueName, NULL, NULL, (PBYTE)szValue, &dwSize) == ERROR_SUCCESS);
470 void QueryDriveMapList_FindNetworkDrives (PDRIVEMAPLIST pList, BOOL *pfFoundNew)
472 for (TCHAR chDrive = chDRIVE_A; chDrive <= chDRIVE_Z; ++chDrive)
474 TCHAR szSubmount[ MAX_PATH ];
475 if (!GetDriveSubmount (chDrive, szSubmount))
478 // We've got a mapping! Drive {chDrive} is mapped to submount
479 // {szSubmount}. See if that submount makes sense.
483 size_t iDrive = chDrive - chDRIVE_A;
484 if (pList->aDriveMap[ iDrive ].szMapping[0] != TEXT('\0'))
486 pList->aDriveMap[ iDrive ].fActive = TRUE;
487 lstrcpy (pList->aDriveMap[ iDrive ].szSubmount, szSubmount);
491 else // (IsWindowsNT())
493 TCHAR szAfsPath[ MAX_PATH ];
494 if (!SubmountToPath (pList, szAfsPath, szSubmount, TRUE))
497 // Okay, we know that drive {chDrive} is mapped to afs path {szAfsPath}.
498 // If this drive is a global afs drive, then reject it. Otherwise, look
499 // at pList->aDriveMap, to see if this drive mapping is already in our
500 // list. If not, add it and set pfFoundNew.
502 if (DriveIsGlobalAfsDrive(chDrive))
505 size_t iDrive = chDrive - chDRIVE_A;
506 if (lstrcmpi (pList->aDriveMap[ iDrive ].szMapping, szAfsPath))
509 pList->aDriveMap[ iDrive ].fPersistent = TRUE;
511 pList->aDriveMap[ iDrive ].fActive = TRUE;
512 pList->aDriveMap[ iDrive ].chDrive = chDrive;
513 lstrcpy (pList->aDriveMap[ iDrive ].szSubmount, szSubmount);
514 AdjustAfsPath (pList->aDriveMap[ iDrive ].szMapping, szAfsPath, TRUE, TRUE);
520 void QueryDriveMapList (PDRIVEMAPLIST pList)
522 // Initialize the data structure
524 memset (pList, 0x00, sizeof(DRIVEMAPLIST));
525 for (size_t ii = 0; ii < 26; ++ii)
526 pList->aDriveMap[ii].chDrive = chDRIVE_A + ii;
528 // Read the current lists of submounts and drive letter mappings
530 QueryDriveMapList_ReadSubmounts (pList);
531 QueryDriveMapList_ReadMappings (pList);
533 // Look through the current list of network drives, and see if
534 // any are currently mapped to AFS. If we find any which are mapped
535 // into AFS unexpectedly, we'll have to rewrite the mappings list.
537 BOOL fFoundNew = FALSE;
538 QueryDriveMapList_FindNetworkDrives (pList, &fFoundNew);
542 QueryDriveMapList_WriteMappings (pList);
547 void FreeDriveMapList (PDRIVEMAPLIST pList)
549 if (pList->aSubmounts)
550 Free (pList->aSubmounts);
551 memset (pList, 0x00, sizeof(DRIVEMAPLIST));
555 BOOL PathToSubmount (LPTSTR pszSubmount, LPTSTR pszMapping, LPTSTR pszSubmountReq, ULONG *pStatus)
557 if (pszSubmountReq && !IsValidSubmountName (pszSubmountReq))
558 pszSubmountReq = NULL;
560 TCHAR szAfsPath[ MAX_PATH ];
561 AdjustAfsPath (szAfsPath, pszMapping, TRUE, TRUE);
563 // Try to ask AFSD for a new submount name.
565 if (!fCanIssuePIOCTL())
568 BYTE InData[ PIOCTL_MAXSIZE ];
569 memset (InData, 0x00, sizeof(InData));
571 LPTSTR pszInData = (LPTSTR)InData;
572 lstrcpy (pszInData, pszMapping);
573 pszInData += 1+lstrlen(pszInData);
575 lstrcpy (pszInData, pszSubmountReq);
577 BYTE OutData[ PIOCTL_MAXSIZE ];
578 memset (OutData, 0x00, sizeof(OutData));
580 struct ViceIoctl IOInfo;
581 IOInfo.in = (char *)InData;
582 IOInfo.in_size = PIOCTL_MAXSIZE;
583 IOInfo.out = (char *)OutData;
584 IOInfo.out_size = PIOCTL_MAXSIZE;
586 ULONG status = pioctl (0, VIOC_MAKESUBMOUNT, &IOInfo, 1);
593 lstrcpy (pszSubmount, (LPCTSTR)OutData);
594 return (pszSubmount[0] != TEXT('\0')) ? TRUE : FALSE;
598 BOOL ActivateDriveMap (TCHAR chDrive, LPTSTR pszMapping, LPTSTR pszSubmountReq, BOOL fPersistent, DWORD *pdwStatus)
600 // We can only map drives to places in AFS using this function.
602 if ( (lstrncmpi (pszMapping, cm_slash_mount_root, lstrlen(cm_slash_mount_root))) &&
603 (lstrncmpi (pszMapping, cm_back_slash_mount_root, lstrlen(cm_back_slash_mount_root))) )
606 *pdwStatus = ERROR_BAD_NETPATH;
610 // First we have to translate {pszMapping} into a submount, and if there is
611 // no current submount associated with this path, we'll have to make one.
614 TCHAR szSubmount[ MAX_PATH ];
615 if (!PathToSubmount (szSubmount, pszMapping, pszSubmountReq, &status))
622 // We now have a submount name and drive letter--map the network drive.
623 DWORD rc=MountDOSDrive(chDrive,szSubmount,fPersistent);
633 BOOL InactivateDriveMap (TCHAR chDrive, DWORD *pdwStatus)
635 DWORD rc = DisMountDOSDrive(chDrive, FALSE);
645 void AddSubMount (LPTSTR pszSubmount, LPTSTR pszMapping)
647 TCHAR szRHS[ MAX_PATH ];
648 AdjustAfsPath (szRHS, pszMapping, FALSE, TRUE);
650 lstrcpy (szRHS, TEXT("/"));
651 WritePrivateProfileString (cszSECTION_SUBMOUNTS, pszSubmount, szRHS, cszINIFILE);
655 void RemoveSubMount (LPTSTR pszSubmount)
657 WritePrivateProfileString (cszSECTION_SUBMOUNTS, pszSubmount, NULL, cszINIFILE);
661 void AdjustAfsPath (LPTSTR pszTarget, LPCTSTR pszSource, BOOL fWantAFS, BOOL fWantForwardSlashes)
664 lstrcpy (pszTarget, (fWantAFS) ? cm_slash_mount_root : TEXT(""));
665 else if ((*pszSource != TEXT('/')) && (*pszSource != TEXT('\\')))
666 wsprintf (pszTarget, TEXT("%s/%s"),cm_slash_mount_root, pszSource);
667 // We don't want to strip afs off the start if it is part of something for example afscell.company.com
668 else if (fWantAFS && (lstrncmpi (&pszSource[1], cm_mount_root, strlen(cm_mount_root))) || !((pszSource[strlen(cm_slash_mount_root)] == TEXT('/')) ||
669 (pszSource[strlen(cm_slash_mount_root)] == TEXT('\\')) ||
670 (lstrlen(pszSource) == strlen(cm_slash_mount_root))))
671 wsprintf (pszTarget, TEXT("%s%s"),cm_slash_mount_root, pszSource);
672 else if (!fWantAFS && (!lstrncmpi (&pszSource[1], cm_mount_root, strlen(cm_mount_root)) && ((pszSource[strlen(cm_slash_mount_root)] == TEXT('/')) ||
673 (pszSource[strlen(cm_slash_mount_root)] == TEXT('\\')) ||
674 (lstrlen(pszSource) == strlen(cm_slash_mount_root)))))
675 lstrcpy (pszTarget, &pszSource[strlen(cm_slash_mount_root)]);
677 lstrcpy (pszTarget, pszSource);
679 for (LPTSTR pch = pszTarget; *pch; ++pch)
681 if (fWantForwardSlashes)
683 *pch = (*pch == TEXT('\\')) ? TEXT('/') : (*pch);
685 else // (!fWantForwardSlashes)
687 *pch = (*pch == TEXT('/')) ? TEXT('\\') : (*pch);
691 if (lstrlen(pszTarget) &&
692 ((pszTarget[lstrlen(pszTarget)-1] == TEXT('/')) ||
693 (pszTarget[lstrlen(pszTarget)-1] == TEXT('\\'))))
695 pszTarget[lstrlen(pszTarget)-1] = TEXT('\0');
699 BOOL GetDriveSubmount (TCHAR chDrive, LPTSTR pszSubmountNow)
701 TCHAR szDrive[] = TEXT("*:");
702 szDrive[0] = chDrive;
704 TCHAR szMapping[ _MAX_PATH ] = TEXT("");
705 LPTSTR pszSubmount = szMapping;
706 TCHAR szNetBiosName[32];
708 memset(szNetBiosName, '\0', sizeof(szNetBiosName));
709 lana_GetNetbiosName(szNetBiosName, LANA_NETBIOS_NAME_FULL);
710 _tcscat(szNetBiosName, TEXT("\\"));
714 if (!QueryDosDevice (szDrive, szMapping, MAX_PATH))
717 // Now if this is an AFS network drive mapping, {szMapping} will be:
719 // \Device\LanmanRedirector\<Drive>:\<netbiosname>\submount
721 // on Windows NT. On Windows 2000, it will be:
723 // \Device\LanmanRedirector\;<Drive>:0\<netbiosname>\submount
725 // (This is presumably to support multiple drive mappings with
728 // on Windows XP and 2003, it will be :
729 // \Device\LanmanRedirector\;<Drive>:<AuthID>\<netbiosname>\submount
731 // where : <Drive> : DOS drive letter
732 // <AuthID>: Authentication ID, 16 char hex.
733 // <netbiosname>: Netbios name of server
735 if (_tcsnicmp(szMapping, cszLANMANDEVICE, _tcslen(cszLANMANDEVICE)))
737 pszSubmount = &szMapping[ _tcslen(cszLANMANDEVICE) ];
741 if (*(pszSubmount) != TEXT(';'))
746 if (toupper(*(++pszSubmount)) != chDrive)
749 if (*(++pszSubmount) != TEXT(':'))
753 // No longer a safe assumption on XP
755 if (*(++pszSubmount) != TEXT('0'))
760 while (*(++pszSubmount) != TEXT('\\'))
766 // note that szNetBiosName has a '\\' tagged in the end earlier
767 for (++pszSubmount; *pszSubmount && (*pszSubmount != TEXT('\\')); ++pszSubmount)
768 if (!_tcsncicmp(pszSubmount, szNetBiosName, _tcslen(szNetBiosName)))
770 if ((!*pszSubmount) || (*pszSubmount == TEXT('\\')))
773 pszSubmount += _tcslen(szNetBiosName);
775 else // (!IsWindowsNT())
777 DWORD dwSize = MAX_PATH;
778 if (WNetGetConnection (szDrive, szMapping, &dwSize) != NO_ERROR)
780 if (*(pszSubmount++) != TEXT('\\'))
782 if (*(pszSubmount++) != TEXT('\\'))
784 for ( ; *pszSubmount && (*pszSubmount != TEXT('\\')); ++pszSubmount)
785 if (!lstrncmpi (pszSubmount, szNetBiosName, lstrlen(szNetBiosName)))
787 if ((!*pszSubmount) || (*pszSubmount == TEXT('\\')))
789 pszSubmount += lstrlen(szNetBiosName);
792 if (!pszSubmount || !*pszSubmount)
795 lstrcpy (pszSubmountNow, pszSubmount);
799 /* Generate Random User name random acording to time*/
801 TCHAR pUserName[MAXRANDOMNAMELEN]=TEXT("");
802 BOOL fUserName=FALSE;
803 #define AFSLogonOptionName TEXT("System\\CurrentControlSet\\Services\\TransarcAFSDaemon\\NetworkProvider")
805 void SetBitLogonOption(BOOL set,DWORD value)
808 RWLogonOption(FALSE,((set)?value | RWLogonOption(TRUE,0):RWLogonOption(TRUE,0) & ~value) );
811 DWORD RWLogonOption(BOOL read,DWORD value)
813 // if read is true then if value==0 return registry value
814 // if read and value!=0 then use value to test registry, return TRUE if value bits match value read
817 DWORD LSPtype, LSPsize;
822 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, AFSLogonOptionName,0, KEY_QUERY_VALUE, &hk)==ERROR_SUCCESS)
824 LSPsize=sizeof(rval);
825 RegQueryValueEx(hk, "LogonOptions", NULL,
826 &LSPtype, (LPBYTE)&rval, &LSPsize);
829 return (value==0)?rval:((rval & value)==value);
832 if (RegCreateKeyEx (HKEY_LOCAL_MACHINE, AFSLogonOptionName, 0, NULL, 0, KEY_SET_VALUE, NULL, &hk, &dwDisp) == ERROR_SUCCESS)
834 RegSetValueEx(hk,TEXT("LogonOptions"),NULL,REG_DWORD,(LPBYTE)&value,sizeof(value));
841 void MapShareName(char *pszCmdLineA)
846 while (*pszCmdLineA && (*pszCmdLineA != ' '))
852 void GenRandomName(TCHAR *pname,int len)
855 { //user name was passed through command line, use once
859 srand( (unsigned)time( NULL ) );
860 for (int i=0;i<len;i++)
861 pname[i]='a'+(rand() % 26);
867 Make a connection using users name
868 if fUserName then force a connection
871 BOOL TestAndDoMapShare(DWORD dwState)
873 if ((dwState!=SERVICE_RUNNING) || (dwOldState!=SERVICE_START_PENDING))
878 dwOldState=SERVICE_RUNNING;
879 if (RWLogonOption(TRUE,LOGON_OPTION_HIGHSECURITY))
880 return (DoMapShare() && GlobalMountDrive());
881 return GlobalMountDrive();
884 BOOL IsServiceActive()
887 SERVICE_STATUS Status;
888 if ((hManager = OpenSCManager (NULL, NULL, GENERIC_READ)) != NULL)
891 if ((hService = OpenService (hManager, TEXT("TransarcAFSDaemon"), GENERIC_READ)) != NULL)
893 QueryServiceStatus (hService, &Status);
894 CloseServiceHandle (hService);
897 CloseServiceHandle (hManager);
900 return (Status.dwCurrentState == SERVICE_RUNNING) ? TRUE : FALSE;
903 void TestAndDoUnMapShare()
905 if (!RWLogonOption(TRUE,LOGON_OPTION_HIGHSECURITY))
910 void DoUnMapShare(BOOL drivemap) //disconnect drivemap
912 TCHAR szMachine[MAX_PATH],szPath[MAX_PATH];
915 LPNETRESOURCE lpnrLocal,lpnr=NULL;
917 DWORD cbBuffer=16384;
921 memset(szMachine, '\0', sizeof(szMachine));
922 lana_GetNetbiosName(szMachine, LANA_NETBIOS_NAME_FULL);
924 // Initialize the data structure
925 if ((res=WNetOpenEnum(RESOURCE_CONNECTED,RESOURCETYPE_DISK,RESOURCEUSAGE_CONNECTABLE,lpnr,&hEnum))!=NO_ERROR)
927 sprintf(szPath,"\\\\%s\\",szMachine);
929 lpnrLocal=(LPNETRESOURCE) GlobalAlloc(GPTR,cbBuffer);
931 memset(lpnrLocal,0,cbBuffer);
932 if ((res = WNetEnumResource(hEnum,&cEntries,lpnrLocal,&cbBuffer))==NO_ERROR)
934 for (DWORD i=0;i<cEntries;i++)
936 if (strstr(_strlwr(lpnrLocal[i].lpRemoteName),szPath))
938 if ((lpnrLocal[i].lpLocalName) && (strlen(lpnrLocal[i].lpLocalName)>0))
941 DisMountDOSDrive(*lpnrLocal[i].lpLocalName);
942 DEBUG_EVENT1("AFS DriveUnMap","UnMap-Local=%x",res);
945 DisMountDOSDriveFull(lpnrLocal[i].lpRemoteName);
946 DEBUG_EVENT1("AFS DriveUnMap","UnMap-Remote=%x",res);
951 } while (res!=ERROR_NO_MORE_ITEMS);
952 GlobalFree((HGLOBAL)lpnrLocal);
953 WNetCloseEnum(hEnum);
956 BOOL DoMapShareChange()
959 TCHAR szMachine[ MAX_PATH],szPath[MAX_PATH];
962 LPNETRESOURCE lpnrLocal,lpnr=NULL;
965 DWORD cbBuffer=16384;
967 memset(szMachine, '\0', sizeof(szMachine));
968 lana_GetNetbiosName(szMachine, LANA_NETBIOS_NAME_FULL);
970 // Initialize the data structure
971 if (!IsServiceActive())
973 memset (&List, 0x00, sizeof(DRIVEMAPLIST));
974 for (size_t ii = 0; ii < 26; ++ii)
975 List.aDriveMap[ii].chDrive = chDRIVE_A + ii;
976 QueryDriveMapList_ReadSubmounts (&List);
977 if ((res=WNetOpenEnum(RESOURCE_CONNECTED,RESOURCETYPE_DISK,RESOURCEUSAGE_CONNECTABLE,lpnr,&hEnum))!=NO_ERROR)
979 lpnrLocal=(LPNETRESOURCE) GlobalAlloc(GPTR,cbBuffer);
980 sprintf(szPath,"\\\\%s\\",szMachine);
983 memset(lpnrLocal,0,cbBuffer);
984 if ((res = WNetEnumResource(hEnum,&cEntries,lpnrLocal,&cbBuffer))==NO_ERROR)
986 for (DWORD i=0;i<cEntries;i++)
988 if (strstr(_strlwr(lpnrLocal[i].lpRemoteName),szPath)==NULL)
989 continue; //only look at real afs mappings
990 CHAR * pSubmount=strrchr(lpnrLocal[i].lpRemoteName,'\\')+1;
991 if (lstrcmpi(pSubmount,"all")==0)
992 continue; // do not remove 'all'
993 for (DWORD j=0;j<List.cSubmounts;j++)
996 (List.aSubmounts[j].szSubmount[0]) &&
997 (lstrcmpi(List.aSubmounts[j].szSubmount,pSubmount)==0)
1000 List.aSubmounts[j].fInUse=TRUE;
1004 // wasn't on list so lets remove
1005 DisMountDOSDrive(pSubmount);
1009 } while (res!=ERROR_NO_MORE_ITEMS);
1010 GlobalFree((HGLOBAL)lpnrLocal);
1011 WNetCloseEnum(hEnum);
1012 sprintf(szPath,"\\\\%s\\all",szMachine);
1014 // Lets connect all submounts that weren't connectd
1015 DWORD cbUser=MAXRANDOMNAMELEN-1;
1016 CHAR szUser[MAXRANDOMNAMELEN];
1017 CHAR * pUser = NULL;
1018 if (WNetGetUser(szPath,(LPSTR)szUser,&cbUser)!=NO_ERROR) {
1019 if (RWLogonOption(TRUE,LOGON_OPTION_HIGHSECURITY)) {
1020 if (!pUserName[0]) {
1021 GenRandomName(szUser,MAXRANDOMNAMELEN-1);
1028 if ((pUser=strchr(szUser,'\\'))!=NULL)
1032 for (DWORD j=0;j<List.cSubmounts;j++)
1034 if (List.aSubmounts[j].fInUse)
1036 DWORD res=MountDOSDrive(0,List.aSubmounts[j].szSubmount,FALSE,pUser);
1045 BOOL bMappedAll=FALSE;
1047 // Initialize the data structure
1048 DEBUG_EVENT0("AFS DoMapShare");
1049 QueryDriveMapList (&List);
1051 // All connections have been removed
1052 // Lets restore them after making the connection from the random name
1054 TCHAR szMachine[ MAX_PATH],szPath[MAX_PATH];
1055 memset(szMachine, '\0', sizeof(szMachine));
1056 lana_GetNetbiosName(szMachine, LANA_NETBIOS_NAME_FULL);
1057 sprintf(szPath,"\\\\%s\\all",szMachine);
1059 // Lets connect all submounts that weren't connectd
1060 DWORD cbUser=MAXRANDOMNAMELEN-1;
1061 CHAR szUser[MAXRANDOMNAMELEN];
1062 CHAR * pUser = NULL;
1063 if (WNetGetUser(szPath,(LPSTR)szUser,&cbUser)!=NO_ERROR) {
1064 if (RWLogonOption(TRUE,LOGON_OPTION_HIGHSECURITY)) {
1065 if (!pUserName[0]) {
1066 GenRandomName(szUser,MAXRANDOMNAMELEN-1);
1073 if ((pUser=strchr(szUser,'\\'))!=NULL)
1077 for (DWORD i=0;i<List.cSubmounts;i++)
1079 if (List.aSubmounts[i].szSubmount[0])
1081 DWORD res=MountDOSDrive(0,List.aSubmounts[i].szSubmount,FALSE,pUser);
1082 if (lstrcmpi("all",List.aSubmounts[i].szSubmount)==0)
1086 if (!bMappedAll) //make sure all is mapped also
1088 DWORD res=MountDOSDrive(0,"all",FALSE,pUser);
1089 if (res==ERROR_SESSION_CREDENTIAL_CONFLICT)
1091 DisMountDOSDrive("all");
1092 MountDOSDrive(0,"all",FALSE,pUser);
1095 for (TCHAR chDrive = chDRIVE_A; chDrive <= chDRIVE_Z; ++chDrive)
1097 if (List.aDriveMap[chDrive-chDRIVE_A].fActive ||
1098 ForceMapActive(chDrive))
1100 TCHAR szSubmount[ MAX_PATH ];
1101 if (List.aDriveMap[chDrive-chDRIVE_A].szSubmount[0])
1102 lstrcpy(szSubmount,List.aDriveMap[chDrive-chDRIVE_A].szSubmount);
1103 else if (!PathToSubmount (szSubmount, List.aDriveMap[chDrive-chDRIVE_A].szMapping, NULL, NULL))
1106 BOOL fPersistent = List.aDriveMap[chDrive-chDRIVE_A].fPersistent;
1107 if (RWLogonOption(TRUE,LOGON_OPTION_HIGHSECURITY))
1108 fPersistent = FALSE;
1109 DWORD res=MountDOSDrive(chDrive
1111 ,fPersistent,pUser);
1117 BOOL GlobalMountDrive()
1119 char szDriveToMapTo[5];
1121 char szKeyName[256];
1125 DWORD dwSubMountSize;
1126 char unsigned szSubMount[256];
1127 char cm_HostName[200];
1128 DWORD dwType=sizeof(cm_HostName);
1129 if (!IsServiceActive())
1131 if (!GetComputerName(cm_HostName, &dwType))
1133 sprintf(szKeyName, "%s\\GlobalAutoMapper", sAFSConfigKeyName);
1135 dwResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE, szKeyName, 0, KEY_QUERY_VALUE,
1137 if (dwResult != ERROR_SUCCESS)
1141 dwDriveSize = sizeof(szDriveToMapTo);
1142 dwSubMountSize = sizeof(szSubMount);
1143 dwResult = RegEnumValue(hKey, dwIndex++, szDriveToMapTo, &dwDriveSize,
1144 0, &dwType, szSubMount, &dwSubMountSize);
1145 if (dwResult != ERROR_MORE_DATA) {
1146 if (dwResult != ERROR_SUCCESS) {
1147 if (dwResult != ERROR_NO_MORE_ITEMS)
1149 DEBUG_EVENT1("AFS DriveMap","Failed to read GlobalAutoMapper values: %d",dwResult);
1154 dwResult=MountDOSDrive(*szDriveToMapTo,(const char *)szSubMount,FALSE);
1160 DWORD MountDOSDrive(char chDrive,const char *szSubmount,BOOL bPersistent,const char * pUsername)
1162 TCHAR szPath[MAX_PATH];
1163 TCHAR szClient[MAX_PATH];
1164 TCHAR szDrive[3] = TEXT("?:");
1165 sprintf(szDrive,"%c:",chDrive);
1166 GetClientNetbiosName (szClient);
1167 sprintf(szPath,"\\\\%s\\%s",szClient,szSubmount);
1169 memset (&nr, 0x00, sizeof(NETRESOURCE));
1170 nr.dwType=RESOURCETYPE_DISK;
1171 nr.lpLocalName=szDrive;
1172 nr.lpRemoteName=szPath;
1173 nr.dwDisplayType = RESOURCEDISPLAYTYPE_SHARE;
1174 DWORD res=WNetAddConnection2(&nr,NULL,pUsername,(bPersistent)?CONNECT_UPDATE_PROFILE:0);
1175 DEBUG_EVENT5("AFS DriveMap","Mount %s Local[%s] Remote[%s] User[%s]=%x",
1176 (bPersistent)?"Persistant" : "NonPresistant",
1177 szDrive,szPath,pUsername?pUsername:"NULL",res);
1181 DWORD DisMountDOSDriveFull(const char *szPath,BOOL bForce)
1183 DWORD res=WNetCancelConnection(szPath,bForce);
1184 DEBUG_EVENT3("AFS DriveMap","%sDismount Remote[%s]=%x",
1185 bForce ? "Forced " : "",szPath,res);
1186 return (res==ERROR_NOT_CONNECTED)?NO_ERROR:res;
1189 DWORD DisMountDOSDrive(const char *pSubmount,BOOL bForce)
1191 TCHAR szPath[MAX_PATH];
1192 TCHAR szClient[MAX_PATH];
1193 GetClientNetbiosName (szClient);
1194 sprintf(szPath,"\\\\%s\\%s",szClient,pSubmount);
1195 return DisMountDOSDriveFull(szPath,bForce);
1199 DWORD DisMountDOSDrive(const char chDrive,BOOL bForce)
1201 TCHAR szPath[MAX_PATH];
1202 sprintf(szPath,"%c:",chDrive);
1203 return DisMountDOSDriveFull(szPath,bForce);