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 static TCHAR szNetbiosName[32] = "";
193 if ( szNetbiosName[0] == 0 ) {
194 lana_GetNetbiosName(szNetbiosName, LANA_NETBIOS_NAME_FULL);
196 _tcscpy(pszName, szNetbiosName);
200 BOOL SubmountToPath (PDRIVEMAPLIST pList, LPTSTR pszPath, LPTSTR pszSubmount, BOOL fMarkInUse)
202 // We can't do this translation unless we're under Windows NT.
207 // \\computer-afs\all always maps to "/afs"
209 if (!lstrcmpi (pszSubmount, TEXT("all")))
211 lstrcpy (pszPath, cm_slash_mount_root);
215 // Otherwise, look up our list of submounts.
217 for (size_t ii = 0; ii < pList->cSubmounts; ++ii)
219 if (!lstrcmpi (pList->aSubmounts[ii].szSubmount, pszSubmount))
222 pList->aSubmounts[ii].fInUse = TRUE;
223 AdjustAfsPath (pszPath, pList->aSubmounts[ii].szMapping, TRUE, TRUE);
232 BOOL IsValidSubmountName (LPTSTR pszSubmount)
236 if (lstrlen (pszSubmount) > 12)
239 for ( ; *pszSubmount; ++pszSubmount)
241 if (!isprint(*pszSubmount))
243 if (*pszSubmount == TEXT(' '))
245 if (*pszSubmount == TEXT('\t'))
254 * PIOCTL SUPPORT _____________________________________________________________
260 #include "../afsd/fs_utils.h"
262 #define __CM_CONFIG_INTERFACES_ONLY__
263 #include "../afsd/cm_config.h"
265 #define __CM_IOCTL_INTERFACES_ONLY__
266 #include "../afsd/cm_ioctl.h"
270 #define PIOCTL_MAXSIZE 2048
273 BOOL fCanIssuePIOCTL (void)
277 TCHAR szGateway[ 256 ] = TEXT("");
278 GetClientNetbiosName (szGateway);
279 return (szGateway[0]) ? TRUE : FALSE;
282 SERVICE_STATUS Status;
283 memset (&Status, 0x00, sizeof(Status));
284 Status.dwCurrentState = SERVICE_STOPPED;
287 if ((hManager = OpenSCManager (NULL, NULL, GENERIC_READ)) != NULL)
290 if ((hService = OpenService (hManager, TEXT("TransarcAFSDaemon"), GENERIC_READ)) != NULL)
292 QueryServiceStatus (hService, &Status);
293 CloseServiceHandle (hService);
296 CloseServiceHandle (hManager);
299 return (Status.dwCurrentState == SERVICE_RUNNING) ? TRUE : FALSE;
304 * QUERYDRIVEMAPLIST __________________________________________________________
308 void QueryDriveMapList_ReadSubmounts (PDRIVEMAPLIST pList)
312 size_t cchLHS = 1024;
313 LPTSTR mszLHS = AllocateStringMemory (cchLHS);
315 for (int iRetry = 0; iRetry < 5; ++iRetry)
317 DWORD rc = GetPrivateProfileString (cszSECTION_SUBMOUNTS, NULL, TEXT(""), mszLHS, cchLHS, cszINIFILE);
318 if ((rc != cchLHS-1) && (rc != cchLHS-2))
321 FreeStringMemory (mszLHS);
323 mszLHS = AllocateStringMemory (cchLHS);
326 for (LPTSTR psz = mszLHS; psz && *psz; psz += 1+lstrlen(psz))
329 memset (&Submount, 0x00, sizeof(SUBMOUNT));
330 lstrcpy (Submount.szSubmount, psz);
332 TCHAR szMapping[ MAX_PATH ] = TEXT("");
333 GetPrivateProfileString (cszSECTION_SUBMOUNTS, Submount.szSubmount, TEXT(""), szMapping, MAX_PATH, cszINIFILE);
334 if (szMapping[0] != TEXT('\0'))
336 AdjustAfsPath (Submount.szMapping, szMapping, FALSE, TRUE);
338 for (size_t ii = 0; ii < pList->cSubmounts; ++ii)
340 if (!pList->aSubmounts[ii].szSubmount[0])
343 if (REALLOC (pList->aSubmounts, pList->cSubmounts, 1+ii, cREALLOC_SUBMOUNTS))
345 memcpy (&pList->aSubmounts[ii], &Submount, sizeof(SUBMOUNT));
350 FreeStringMemory (mszLHS);
355 void QueryDriveMapList_ReadMappings (PDRIVEMAPLIST pList)
357 size_t cchLHS = 1024;
358 LPTSTR mszLHS = AllocateStringMemory (cchLHS);
360 for (int iRetry = 0; iRetry < 5; ++iRetry)
362 DWORD rc = GetPrivateProfileString (cszSECTION_MAPPINGS, NULL, TEXT(""), mszLHS, cchLHS, cszINIFILE);
363 if ((rc != cchLHS-1) && (rc != cchLHS-2))
366 FreeStringMemory (mszLHS);
368 mszLHS = AllocateStringMemory (cchLHS);
371 for (LPTSTR psz = mszLHS; psz && *psz; psz += 1+lstrlen(psz))
374 memset (&DriveMap, 0x00, sizeof(DRIVEMAP));
375 DriveMap.chDrive = toupper(*psz);
376 DriveMap.fPersistent = TRUE;
377 if ((DriveMap.chDrive < chDRIVE_A) || (DriveMap.chDrive > chDRIVE_Z))
380 TCHAR szMapping[ MAX_PATH ] = TEXT("");
381 GetPrivateProfileString (cszSECTION_MAPPINGS, psz, TEXT(""), szMapping, MAX_PATH, cszINIFILE);
382 if (szMapping[0] != TEXT('\0'))
384 AdjustAfsPath (DriveMap.szMapping, szMapping, TRUE, TRUE);
385 if (DriveMap.szMapping[ lstrlen(DriveMap.szMapping)-1 ] == TEXT('*'))
387 DriveMap.fPersistent = FALSE;
388 DriveMap.szMapping[ lstrlen(DriveMap.szMapping)-1 ] = TEXT('\0');
390 size_t iDrive = DriveMap.chDrive - chDRIVE_A;
391 memcpy (&pList->aDriveMap[ iDrive ], &DriveMap, sizeof(DRIVEMAP));
395 FreeStringMemory (mszLHS);
398 BOOL ForceMapActive (TCHAR chDrive)
403 szDrive[0] = chDrive;
406 GetPrivateProfileString (cszSECTION_ACTIVE, szDrive, TEXT("0"), szActive, sizeof(szActive), cszINIFILE);
408 if ( !lstrcmp(szActive,"1") || !lstrcmpi(szActive,"true") || !lstrcmpi(szActive,"on") || !lstrcmpi(szActive,"yes") )
414 void WriteActiveMap (TCHAR chDrive, BOOL on)
418 szDrive[0] = chDrive;
421 WritePrivateProfileString (cszSECTION_ACTIVE, szDrive, on ? "1" : "0", cszINIFILE);
424 void QueryDriveMapList_WriteMappings (PDRIVEMAPLIST pList)
426 WriteDriveMappings (pList);
430 void WriteDriveMappings (PDRIVEMAPLIST pList)
432 WritePrivateProfileString (cszSECTION_MAPPINGS, NULL, NULL, cszINIFILE);
434 for (size_t iDrive = 0; iDrive < 26; ++iDrive)
436 if (pList->aDriveMap[iDrive].szMapping[0] != TEXT('\0'))
438 TCHAR szLHS[] = TEXT("*");
439 szLHS[0] = pList->aDriveMap[iDrive].chDrive;
441 TCHAR szRHS[MAX_PATH];
442 AdjustAfsPath (szRHS, pList->aDriveMap[iDrive].szMapping, TRUE, TRUE);
443 if (!pList->aDriveMap[iDrive].fPersistent)
444 lstrcat (szRHS, TEXT("*"));
446 WritePrivateProfileString (cszSECTION_MAPPINGS, szLHS, szRHS, cszINIFILE);
451 BOOL DriveIsGlobalAfsDrive(TCHAR chDrive)
453 TCHAR szKeyName[128];
454 TCHAR szValueName[128];
458 _stprintf(szKeyName, TEXT("%s\\GlobalAutoMapper"), sAFSConfigKeyName);
460 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, szKeyName, 0, KEY_QUERY_VALUE, &hKey) != ERROR_SUCCESS)
463 _stprintf(szValueName, TEXT("%c:"), chDrive);
465 DWORD dwSize = sizeof(szValue);
466 BOOL bIsGlobal = (RegQueryValueEx (hKey, szValueName, NULL, NULL, (PBYTE)szValue, &dwSize) == ERROR_SUCCESS);
474 void QueryDriveMapList_FindNetworkDrives (PDRIVEMAPLIST pList, BOOL *pfFoundNew)
476 for (TCHAR chDrive = chDRIVE_A; chDrive <= chDRIVE_Z; ++chDrive)
478 TCHAR szSubmount[ MAX_PATH ];
479 if (!GetDriveSubmount (chDrive, szSubmount))
482 // We've got a mapping! Drive {chDrive} is mapped to submount
483 // {szSubmount}. See if that submount makes sense.
487 size_t iDrive = chDrive - chDRIVE_A;
488 if (pList->aDriveMap[ iDrive ].szMapping[0] != TEXT('\0'))
490 pList->aDriveMap[ iDrive ].fActive = TRUE;
491 lstrcpy (pList->aDriveMap[ iDrive ].szSubmount, szSubmount);
495 else // (IsWindowsNT())
497 TCHAR szAfsPath[ MAX_PATH ];
498 if (!SubmountToPath (pList, szAfsPath, szSubmount, TRUE))
501 // Okay, we know that drive {chDrive} is mapped to afs path {szAfsPath}.
502 // If this drive is a global afs drive, then reject it. Otherwise, look
503 // at pList->aDriveMap, to see if this drive mapping is already in our
504 // list. If not, add it and set pfFoundNew.
506 if (DriveIsGlobalAfsDrive(chDrive))
509 size_t iDrive = chDrive - chDRIVE_A;
510 if (lstrcmpi (pList->aDriveMap[ iDrive ].szMapping, szAfsPath))
513 pList->aDriveMap[ iDrive ].fPersistent = TRUE;
515 pList->aDriveMap[ iDrive ].fActive = TRUE;
516 pList->aDriveMap[ iDrive ].chDrive = chDrive;
517 lstrcpy (pList->aDriveMap[ iDrive ].szSubmount, szSubmount);
518 AdjustAfsPath (pList->aDriveMap[ iDrive ].szMapping, szAfsPath, TRUE, TRUE);
524 void QueryDriveMapList (PDRIVEMAPLIST pList)
526 // Initialize the data structure
528 memset (pList, 0x00, sizeof(DRIVEMAPLIST));
529 for (size_t ii = 0; ii < 26; ++ii)
530 pList->aDriveMap[ii].chDrive = chDRIVE_A + ii;
532 // Read the current lists of submounts and drive letter mappings
534 QueryDriveMapList_ReadSubmounts (pList);
535 QueryDriveMapList_ReadMappings (pList);
537 // Look through the current list of network drives, and see if
538 // any are currently mapped to AFS. If we find any which are mapped
539 // into AFS unexpectedly, we'll have to rewrite the mappings list.
541 BOOL fFoundNew = FALSE;
542 QueryDriveMapList_FindNetworkDrives (pList, &fFoundNew);
546 QueryDriveMapList_WriteMappings (pList);
551 void FreeDriveMapList (PDRIVEMAPLIST pList)
553 if (pList->aSubmounts)
554 Free (pList->aSubmounts);
555 memset (pList, 0x00, sizeof(DRIVEMAPLIST));
559 BOOL PathToSubmount (LPTSTR pszSubmount, LPTSTR pszMapping, LPTSTR pszSubmountReq, ULONG *pStatus)
561 if (pszSubmountReq && !IsValidSubmountName (pszSubmountReq))
562 pszSubmountReq = NULL;
564 TCHAR szAfsPath[ MAX_PATH ];
565 AdjustAfsPath (szAfsPath, pszMapping, TRUE, TRUE);
567 // Try to ask AFSD for a new submount name.
569 if (!fCanIssuePIOCTL())
572 BYTE InData[ PIOCTL_MAXSIZE ];
573 memset (InData, 0x00, sizeof(InData));
575 LPTSTR pszInData = (LPTSTR)InData;
576 lstrcpy (pszInData, pszMapping);
577 pszInData += 1+lstrlen(pszInData);
579 lstrcpy (pszInData, pszSubmountReq);
581 BYTE OutData[ PIOCTL_MAXSIZE ];
582 memset (OutData, 0x00, sizeof(OutData));
584 struct ViceIoctl IOInfo;
585 IOInfo.in = (char *)InData;
586 IOInfo.in_size = PIOCTL_MAXSIZE;
587 IOInfo.out = (char *)OutData;
588 IOInfo.out_size = PIOCTL_MAXSIZE;
590 ULONG status = pioctl (0, VIOC_MAKESUBMOUNT, &IOInfo, 1);
597 lstrcpy (pszSubmount, (LPCTSTR)OutData);
598 return (pszSubmount[0] != TEXT('\0')) ? TRUE : FALSE;
602 BOOL ActivateDriveMap (TCHAR chDrive, LPTSTR pszMapping, LPTSTR pszSubmountReq, BOOL fPersistent, DWORD *pdwStatus)
604 // We can only map drives to places in AFS using this function.
606 if ( (lstrncmpi (pszMapping, cm_slash_mount_root, lstrlen(cm_slash_mount_root))) &&
607 (lstrncmpi (pszMapping, cm_back_slash_mount_root, lstrlen(cm_back_slash_mount_root))) )
610 *pdwStatus = ERROR_BAD_NETPATH;
614 // First we have to translate {pszMapping} into a submount, and if there is
615 // no current submount associated with this path, we'll have to make one.
618 TCHAR szSubmount[ MAX_PATH ];
619 if (!PathToSubmount (szSubmount, pszMapping, pszSubmountReq, &status))
626 // We now have a submount name and drive letter--map the network drive.
627 DWORD rc=MountDOSDrive(chDrive,szSubmount,fPersistent);
637 BOOL InactivateDriveMap (TCHAR chDrive, DWORD *pdwStatus)
639 DWORD rc = DisMountDOSDrive(chDrive, FALSE);
649 void AddSubMount (LPTSTR pszSubmount, LPTSTR pszMapping)
651 TCHAR szRHS[ MAX_PATH ];
652 AdjustAfsPath (szRHS, pszMapping, FALSE, TRUE);
654 lstrcpy (szRHS, TEXT("/"));
655 WritePrivateProfileString (cszSECTION_SUBMOUNTS, pszSubmount, szRHS, cszINIFILE);
659 void RemoveSubMount (LPTSTR pszSubmount)
661 WritePrivateProfileString (cszSECTION_SUBMOUNTS, pszSubmount, NULL, cszINIFILE);
665 void AdjustAfsPath (LPTSTR pszTarget, LPCTSTR pszSource, BOOL fWantAFS, BOOL fWantForwardSlashes)
668 lstrcpy (pszTarget, (fWantAFS) ? cm_slash_mount_root : TEXT(""));
669 else if ((*pszSource != TEXT('/')) && (*pszSource != TEXT('\\')))
670 wsprintf (pszTarget, TEXT("%s/%s"),cm_slash_mount_root, pszSource);
671 // We don't want to strip afs off the start if it is part of something for example afscell.company.com
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 wsprintf (pszTarget, TEXT("%s%s"),cm_slash_mount_root, pszSource);
676 else if (!fWantAFS && (!lstrncmpi (&pszSource[1], cm_mount_root, strlen(cm_mount_root)) && ((pszSource[strlen(cm_slash_mount_root)] == TEXT('/')) ||
677 (pszSource[strlen(cm_slash_mount_root)] == TEXT('\\')) ||
678 (lstrlen(pszSource) == strlen(cm_slash_mount_root)))))
679 lstrcpy (pszTarget, &pszSource[strlen(cm_slash_mount_root)]);
681 lstrcpy (pszTarget, pszSource);
683 for (LPTSTR pch = pszTarget; *pch; ++pch)
685 if (fWantForwardSlashes)
687 *pch = (*pch == TEXT('\\')) ? TEXT('/') : (*pch);
689 else // (!fWantForwardSlashes)
691 *pch = (*pch == TEXT('/')) ? TEXT('\\') : (*pch);
695 if (lstrlen(pszTarget) &&
696 ((pszTarget[lstrlen(pszTarget)-1] == TEXT('/')) ||
697 (pszTarget[lstrlen(pszTarget)-1] == TEXT('\\'))))
699 pszTarget[lstrlen(pszTarget)-1] = TEXT('\0');
703 BOOL GetDriveSubmount (TCHAR chDrive, LPTSTR pszSubmountNow)
705 BOOL isWinNT = IsWindowsNT();
707 TCHAR szDrive[] = TEXT("*:");
708 szDrive[0] = chDrive;
710 TCHAR szMapping[ _MAX_PATH ] = TEXT("");
712 if (isWinNT && !QueryDosDevice (szDrive, szMapping, MAX_PATH))
715 LPTSTR pszSubmount = szMapping;
717 TCHAR szNetBiosName[32];
718 memset(szNetBiosName, '\0', sizeof(szNetBiosName));
719 GetClientNetbiosName(szNetBiosName);
720 _tcscat(szNetBiosName, TEXT("\\"));
724 // Now if this is an AFS network drive mapping, {szMapping} will be:
726 // \Device\LanmanRedirector\<Drive>:\<netbiosname>\submount
728 // on Windows NT. On Windows 2000, it will be:
730 // \Device\LanmanRedirector\;<Drive>:0\<netbiosname>\submount
732 // (This is presumably to support multiple drive mappings with
735 // on Windows XP and 2003, it will be :
736 // \Device\LanmanRedirector\;<Drive>:<AuthID>\<netbiosname>\submount
738 // where : <Drive> : DOS drive letter
739 // <AuthID>: Authentication ID, 16 char hex.
740 // <netbiosname>: Netbios name of server
742 if (_tcsnicmp(szMapping, cszLANMANDEVICE, _tcslen(cszLANMANDEVICE)))
744 pszSubmount = &szMapping[ _tcslen(cszLANMANDEVICE) ];
748 if (*(pszSubmount) != TEXT(';'))
753 if (toupper(*(++pszSubmount)) != chDrive)
756 if (*(++pszSubmount) != TEXT(':'))
760 // No longer a safe assumption on XP
762 if (*(++pszSubmount) != TEXT('0'))
767 while (*(++pszSubmount) != TEXT('\\'))
773 // note that szNetBiosName has a '\\' tagged in the end earlier
774 for (++pszSubmount; *pszSubmount && (*pszSubmount != TEXT('\\')); ++pszSubmount)
775 if (!_tcsncicmp(pszSubmount, szNetBiosName, _tcslen(szNetBiosName)))
777 if ((!*pszSubmount) || (*pszSubmount == TEXT('\\')))
780 pszSubmount += _tcslen(szNetBiosName);
782 else // (!IsWindowsNT())
784 DWORD dwSize = MAX_PATH;
785 if (WNetGetConnection (szDrive, szMapping, &dwSize) != NO_ERROR)
787 if (*(pszSubmount++) != TEXT('\\'))
789 if (*(pszSubmount++) != TEXT('\\'))
791 for ( ; *pszSubmount && (*pszSubmount != TEXT('\\')); ++pszSubmount)
792 if (!lstrncmpi (pszSubmount, szNetBiosName, lstrlen(szNetBiosName)))
794 if ((!*pszSubmount) || (*pszSubmount == TEXT('\\')))
796 pszSubmount += lstrlen(szNetBiosName);
799 if (!pszSubmount || !*pszSubmount)
802 lstrcpy (pszSubmountNow, pszSubmount);
806 /* Generate Random User name random acording to time*/
808 TCHAR pUserName[MAXRANDOMNAMELEN]=TEXT("");
809 BOOL fUserName=FALSE;
810 #define AFSLogonOptionName TEXT("System\\CurrentControlSet\\Services\\TransarcAFSDaemon\\NetworkProvider")
812 void SetBitLogonOption(BOOL set,DWORD value)
815 RWLogonOption(FALSE,((set)?value | RWLogonOption(TRUE,0):RWLogonOption(TRUE,0) & ~value) );
818 DWORD RWLogonOption(BOOL read,DWORD value)
820 // if read is true then if value==0 return registry value
821 // if read and value!=0 then use value to test registry, return TRUE if value bits match value read
824 DWORD LSPtype, LSPsize;
829 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, AFSLogonOptionName,0, KEY_QUERY_VALUE, &hk)==ERROR_SUCCESS)
831 LSPsize=sizeof(rval);
832 RegQueryValueEx(hk, "LogonOptions", NULL,
833 &LSPtype, (LPBYTE)&rval, &LSPsize);
836 return (value==0)?rval:((rval & value)==value);
839 if (RegCreateKeyEx (HKEY_LOCAL_MACHINE, AFSLogonOptionName, 0, NULL, 0, KEY_SET_VALUE, NULL, &hk, &dwDisp) == ERROR_SUCCESS)
841 RegSetValueEx(hk,TEXT("LogonOptions"),NULL,REG_DWORD,(LPBYTE)&value,sizeof(value));
848 void MapShareName(char *pszCmdLineA)
853 while (*pszCmdLineA && (*pszCmdLineA != ' '))
859 void GenRandomName(TCHAR *pname,int len)
862 { //user name was passed through command line, use once
866 srand( (unsigned)time( NULL ) );
867 for (int i=0;i<len;i++)
868 pname[i]='a'+(rand() % 26);
874 Make a connection using users name
875 if fUserName then force a connection
878 BOOL TestAndDoMapShare(DWORD dwState)
880 if ((dwState!=SERVICE_RUNNING) || (dwOldState!=SERVICE_START_PENDING))
885 dwOldState=SERVICE_RUNNING;
886 if (RWLogonOption(TRUE,LOGON_OPTION_HIGHSECURITY))
887 return (DoMapShare() && GlobalMountDrive());
888 return GlobalMountDrive();
891 BOOL IsServiceActive()
894 SERVICE_STATUS Status;
895 if ((hManager = OpenSCManager (NULL, NULL, GENERIC_READ)) != NULL)
898 if ((hService = OpenService (hManager, TEXT("TransarcAFSDaemon"), GENERIC_READ)) != NULL)
900 QueryServiceStatus (hService, &Status);
901 CloseServiceHandle (hService);
904 CloseServiceHandle (hManager);
907 return (Status.dwCurrentState == SERVICE_RUNNING) ? TRUE : FALSE;
910 void TestAndDoUnMapShare()
912 if (!RWLogonOption(TRUE,LOGON_OPTION_HIGHSECURITY))
917 void DoUnMapShare(BOOL drivemap) //disconnect drivemap
919 TCHAR szMachine[MAX_PATH],szPath[MAX_PATH];
922 LPNETRESOURCE lpnrLocal,lpnr=NULL;
924 DWORD cbBuffer=16384;
928 memset(szMachine, '\0', sizeof(szMachine));
929 GetClientNetbiosName(szMachine);
931 // Initialize the data structure
932 if ((res=WNetOpenEnum(RESOURCE_CONNECTED,RESOURCETYPE_DISK,RESOURCEUSAGE_CONNECTABLE,lpnr,&hEnum))!=NO_ERROR)
934 sprintf(szPath,"\\\\%s\\",szMachine);
936 lpnrLocal=(LPNETRESOURCE) GlobalAlloc(GPTR,cbBuffer);
938 memset(lpnrLocal,0,cbBuffer);
939 if ((res = WNetEnumResource(hEnum,&cEntries,lpnrLocal,&cbBuffer))==NO_ERROR)
941 for (DWORD i=0;i<cEntries;i++)
943 if (strstr(_strlwr(lpnrLocal[i].lpRemoteName),szPath))
945 if ((lpnrLocal[i].lpLocalName) && (strlen(lpnrLocal[i].lpLocalName)>0))
948 DisMountDOSDrive(*lpnrLocal[i].lpLocalName);
949 DEBUG_EVENT1("AFS DriveUnMap","UnMap-Local=%x",res);
952 DisMountDOSDriveFull(lpnrLocal[i].lpRemoteName);
953 DEBUG_EVENT1("AFS DriveUnMap","UnMap-Remote=%x",res);
958 } while (res!=ERROR_NO_MORE_ITEMS);
959 GlobalFree((HGLOBAL)lpnrLocal);
960 WNetCloseEnum(hEnum);
963 BOOL DoMapShareChange()
966 TCHAR szMachine[ MAX_PATH],szPath[MAX_PATH];
969 LPNETRESOURCE lpnrLocal,lpnr=NULL;
972 DWORD cbBuffer=16384;
974 memset(szMachine, '\0', sizeof(szMachine));
975 GetClientNetbiosName(szMachine);
977 // Initialize the data structure
978 if (!IsServiceActive())
980 memset (&List, 0x00, sizeof(DRIVEMAPLIST));
981 for (size_t ii = 0; ii < 26; ++ii)
982 List.aDriveMap[ii].chDrive = chDRIVE_A + ii;
983 QueryDriveMapList_ReadSubmounts (&List);
984 if ((res=WNetOpenEnum(RESOURCE_CONNECTED,RESOURCETYPE_DISK,RESOURCEUSAGE_CONNECTABLE,lpnr,&hEnum))!=NO_ERROR)
986 lpnrLocal=(LPNETRESOURCE) GlobalAlloc(GPTR,cbBuffer);
987 sprintf(szPath,"\\\\%s\\",szMachine);
990 memset(lpnrLocal,0,cbBuffer);
991 if ((res = WNetEnumResource(hEnum,&cEntries,lpnrLocal,&cbBuffer))==NO_ERROR)
993 for (DWORD i=0;i<cEntries;i++)
995 if (strstr(_strlwr(lpnrLocal[i].lpRemoteName),szPath)==NULL)
996 continue; //only look at real afs mappings
997 CHAR * pSubmount=strrchr(lpnrLocal[i].lpRemoteName,'\\')+1;
998 if (lstrcmpi(pSubmount,"all")==0)
999 continue; // do not remove 'all'
1000 for (DWORD j=0;j<List.cSubmounts;j++)
1003 (List.aSubmounts[j].szSubmount[0]) &&
1004 (lstrcmpi(List.aSubmounts[j].szSubmount,pSubmount)==0)
1007 List.aSubmounts[j].fInUse=TRUE;
1011 // wasn't on list so lets remove
1012 DisMountDOSDrive(pSubmount);
1016 } while (res!=ERROR_NO_MORE_ITEMS);
1017 GlobalFree((HGLOBAL)lpnrLocal);
1018 WNetCloseEnum(hEnum);
1019 sprintf(szPath,"\\\\%s\\all",szMachine);
1021 // Lets connect all submounts that weren't connectd
1022 DWORD cbUser=MAXRANDOMNAMELEN-1;
1023 CHAR szUser[MAXRANDOMNAMELEN];
1024 CHAR * pUser = NULL;
1025 if (WNetGetUser(szPath,(LPSTR)szUser,&cbUser)!=NO_ERROR) {
1026 if (RWLogonOption(TRUE,LOGON_OPTION_HIGHSECURITY)) {
1027 if (!pUserName[0]) {
1028 GenRandomName(szUser,MAXRANDOMNAMELEN-1);
1035 if ((pUser=strchr(szUser,'\\'))!=NULL)
1039 for (DWORD j=0;j<List.cSubmounts;j++)
1041 if (List.aSubmounts[j].fInUse)
1043 DWORD res=MountDOSDrive(0,List.aSubmounts[j].szSubmount,FALSE,pUser);
1052 BOOL bMappedAll=FALSE;
1054 // Initialize the data structure
1055 DEBUG_EVENT0("AFS DoMapShare");
1056 QueryDriveMapList (&List);
1058 // All connections have been removed
1059 // Lets restore them after making the connection from the random name
1061 TCHAR szMachine[ MAX_PATH],szPath[MAX_PATH];
1062 memset(szMachine, '\0', sizeof(szMachine));
1063 GetClientNetbiosName(szMachine);
1064 sprintf(szPath,"\\\\%s\\all",szMachine);
1066 // Lets connect all submounts that weren't connectd
1067 DWORD cbUser=MAXRANDOMNAMELEN-1;
1068 CHAR szUser[MAXRANDOMNAMELEN];
1069 CHAR * pUser = NULL;
1070 if (WNetGetUser(szPath,(LPSTR)szUser,&cbUser)!=NO_ERROR) {
1071 if (RWLogonOption(TRUE,LOGON_OPTION_HIGHSECURITY)) {
1072 if (!pUserName[0]) {
1073 GenRandomName(szUser,MAXRANDOMNAMELEN-1);
1080 if ((pUser=strchr(szUser,'\\'))!=NULL)
1084 for (DWORD i=0;i<List.cSubmounts;i++)
1086 if (List.aSubmounts[i].szSubmount[0])
1088 DWORD res=MountDOSDrive(0,List.aSubmounts[i].szSubmount,FALSE,pUser);
1089 if (lstrcmpi("all",List.aSubmounts[i].szSubmount)==0)
1093 if (!bMappedAll) //make sure all is mapped also
1095 DWORD res=MountDOSDrive(0,"all",FALSE,pUser);
1096 if (res==ERROR_SESSION_CREDENTIAL_CONFLICT)
1098 DisMountDOSDrive("all");
1099 MountDOSDrive(0,"all",FALSE,pUser);
1102 for (TCHAR chDrive = chDRIVE_A; chDrive <= chDRIVE_Z; ++chDrive)
1104 if (List.aDriveMap[chDrive-chDRIVE_A].fActive ||
1105 ForceMapActive(chDrive))
1107 TCHAR szSubmount[ MAX_PATH ];
1108 if (List.aDriveMap[chDrive-chDRIVE_A].szSubmount[0])
1109 lstrcpy(szSubmount,List.aDriveMap[chDrive-chDRIVE_A].szSubmount);
1110 else if (!PathToSubmount (szSubmount, List.aDriveMap[chDrive-chDRIVE_A].szMapping, NULL, NULL))
1113 BOOL fPersistent = List.aDriveMap[chDrive-chDRIVE_A].fPersistent;
1114 if (RWLogonOption(TRUE,LOGON_OPTION_HIGHSECURITY))
1115 fPersistent = FALSE;
1116 DWORD res=MountDOSDrive(chDrive
1118 ,fPersistent,pUser);
1124 BOOL GlobalMountDrive()
1126 char szDriveToMapTo[5];
1128 char szKeyName[256];
1132 DWORD dwSubMountSize;
1133 char unsigned szSubMount[256];
1134 char cm_HostName[200];
1135 DWORD dwType=sizeof(cm_HostName);
1136 if (!IsServiceActive())
1138 if (!GetComputerName(cm_HostName, &dwType))
1140 sprintf(szKeyName, "%s\\GlobalAutoMapper", sAFSConfigKeyName);
1142 dwResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE, szKeyName, 0, KEY_QUERY_VALUE,
1144 if (dwResult != ERROR_SUCCESS)
1148 dwDriveSize = sizeof(szDriveToMapTo);
1149 dwSubMountSize = sizeof(szSubMount);
1150 dwResult = RegEnumValue(hKey, dwIndex++, szDriveToMapTo, &dwDriveSize,
1151 0, &dwType, szSubMount, &dwSubMountSize);
1152 if (dwResult != ERROR_MORE_DATA) {
1153 if (dwResult != ERROR_SUCCESS) {
1154 if (dwResult != ERROR_NO_MORE_ITEMS)
1156 DEBUG_EVENT1("AFS DriveMap","Failed to read GlobalAutoMapper values: %d",dwResult);
1161 dwResult=MountDOSDrive(*szDriveToMapTo,(const char *)szSubMount,FALSE);
1167 DWORD MountDOSDrive(char chDrive,const char *szSubmount,BOOL bPersistent,const char * pUsername)
1169 TCHAR szPath[MAX_PATH];
1170 TCHAR szClient[MAX_PATH];
1171 TCHAR szDrive[3] = TEXT("?:");
1172 sprintf(szDrive,"%c:",chDrive);
1173 GetClientNetbiosName (szClient);
1174 sprintf(szPath,"\\\\%s\\%s",szClient,szSubmount);
1176 memset (&nr, 0x00, sizeof(NETRESOURCE));
1177 nr.dwType=RESOURCETYPE_DISK;
1178 nr.lpLocalName=szDrive;
1179 nr.lpRemoteName=szPath;
1180 nr.dwDisplayType = RESOURCEDISPLAYTYPE_SHARE;
1181 DWORD res=WNetAddConnection2(&nr,NULL,pUsername,(bPersistent)?CONNECT_UPDATE_PROFILE:0);
1182 DEBUG_EVENT5("AFS DriveMap","Mount %s Local[%s] Remote[%s] User[%s]=%x",
1183 (bPersistent)?"Persistant" : "NonPresistant",
1184 szDrive,szPath,pUsername?pUsername:"NULL",res);
1188 DWORD DisMountDOSDriveFull(const char *szPath,BOOL bForce)
1190 DWORD res=WNetCancelConnection(szPath,bForce);
1191 DEBUG_EVENT3("AFS DriveMap","%sDismount Remote[%s]=%x",
1192 bForce ? "Forced " : "",szPath,res);
1193 return (res==ERROR_NOT_CONNECTED)?NO_ERROR:res;
1196 DWORD DisMountDOSDrive(const char *pSubmount,BOOL bForce)
1198 TCHAR szPath[MAX_PATH];
1199 TCHAR szClient[MAX_PATH];
1200 GetClientNetbiosName (szClient);
1201 sprintf(szPath,"\\\\%s\\%s",szClient,pSubmount);
1202 return DisMountDOSDriveFull(szPath,bForce);
1206 DWORD DisMountDOSDrive(const char chDrive,BOOL bForce)
1208 TCHAR szPath[MAX_PATH];
1209 sprintf(szPath,"%c:",chDrive);
1210 return DisMountDOSDriveFull(szPath,bForce);