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);
29 extern BOOL Config_ReadNum (LPCTSTR pszLHS, DWORD *pdwRHS);
30 extern BOOL Config_ReadString (LPCTSTR pszLHS, LPTSTR pszRHS, size_t cchMax);
33 * REGISTRY ___________________________________________________________________
37 #undef AFSConfigKeyName
38 const TCHAR sAFSConfigKeyName[] = TEXT("SYSTEM\\CurrentControlSet\\Services\\TransarcAFSDaemon\\Parameters");
42 * PROFILE SECTIONS ___________________________________________________________
46 #define cREALLOC_SUBMOUNTS 4
48 static TCHAR cszINIFILE[] = TEXT("afsdsbmt.ini");
49 static TCHAR cszSECTION_SUBMOUNTS[] = TEXT("AFS Submounts");
50 static TCHAR cszSECTION_MAPPINGS[] = TEXT("AFS Mappings");
51 static TCHAR cszSECTION_ACTIVE[] = TEXT("AFS Active");
53 static TCHAR cszAUTOSUBMOUNT[] = TEXT("Auto");
54 static TCHAR cszLANMANDEVICE[] = TEXT("\\Device\\LanmanRedirector\\");
58 * STRINGS ____________________________________________________________________
62 static LPTSTR AllocateStringMemory (size_t cch)
64 LPTSTR psz = (LPTSTR)Allocate (sizeof(TCHAR) * (cch+1));
65 memset (psz, 0x00, sizeof(TCHAR) * (cch+1));
69 static void FreeStringMemory (LPTSTR pszString)
74 static int lstrncmpi (LPCTSTR pszA, LPCTSTR pszB, size_t cch)
78 return (!pszB) - (!pszA); // A,!B:1, !A,B:-1, !A,!B:0
81 for ( ; cch > 0; cch--, pszA = CharNext(pszA), pszB = CharNext(pszB))
83 TCHAR chA = toupper( *pszA );
84 TCHAR chB = toupper( *pszB );
87 return (!chB) - (!chA); // A,!B:1, !A,B:-1, !A,!B:0
90 return (int)(chA) - (int)(chB); // -1:A<B, 0:A==B, 1:A>B
93 return 0; // no differences before told to stop comparing, so A==B
98 * REALLOC ____________________________________________________________________
103 #define REALLOC(_a,_c,_r,_i) DriveMapReallocFunction ((LPVOID*)&_a,sizeof(*_a),&_c,_r,_i)
104 BOOL DriveMapReallocFunction (LPVOID *ppTarget, size_t cbElement, size_t *pcTarget, size_t cReq, size_t cInc)
109 if (cReq <= *pcTarget)
112 if ((cNew = cInc * ((cReq + cInc-1) / cInc)) <= 0)
115 if ((pNew = Allocate (cbElement * cNew)) == NULL)
117 memset (pNew, 0x00, cbElement * cNew);
121 memcpy (pNew, *ppTarget, cbElement * (*pcTarget));
133 * WINDOWS NT STUFF ___________________________________________________________
137 static BOOL IsWindowsNT (void)
139 static BOOL fChecked = FALSE;
140 static BOOL fIsWinNT = FALSE;
146 OSVERSIONINFO Version;
147 memset (&Version, 0x00, sizeof(Version));
148 Version.dwOSVersionInfoSize = sizeof(Version);
150 if (GetVersionEx (&Version))
152 if (Version.dwPlatformId == VER_PLATFORM_WIN32_NT)
160 /* Check if the OS is Windows 2000 or higher.
162 BOOL IsWindows2000 (void)
164 static BOOL fChecked = FALSE;
165 static BOOL fIsWin2K = FALSE;
171 OSVERSIONINFO Version;
172 memset (&Version, 0x00, sizeof(Version));
173 Version.dwOSVersionInfoSize = sizeof(Version);
175 if (GetVersionEx (&Version))
177 if (Version.dwPlatformId == VER_PLATFORM_WIN32_NT &&
178 Version.dwMajorVersion >= 5)
187 * GENERAL ____________________________________________________________________
191 void GetClientNetbiosName (LPTSTR pszName)
193 *pszName = TEXT('\0');
194 lana_GetNetbiosName(pszName, LANA_NETBIOS_NAME_FULL);
198 BOOL SubmountToPath (PDRIVEMAPLIST pList, LPTSTR pszPath, LPTSTR pszSubmount, BOOL fMarkInUse)
200 // We can't do this translation unless we're under Windows NT.
205 // \\computer-afs\all always maps to "/afs"
207 if (!lstrcmpi (pszSubmount, TEXT("all")))
209 lstrcpy (pszPath, cm_slash_mount_root);
213 // Otherwise, look up our list of submounts.
215 for (size_t ii = 0; ii < pList->cSubmounts; ++ii)
217 if (!lstrcmpi (pList->aSubmounts[ii].szSubmount, pszSubmount))
220 pList->aSubmounts[ii].fInUse = TRUE;
221 AdjustAfsPath (pszPath, pList->aSubmounts[ii].szMapping, TRUE, TRUE);
230 BOOL IsValidSubmountName (LPTSTR pszSubmount)
234 if (lstrlen (pszSubmount) > 12)
237 for ( ; *pszSubmount; ++pszSubmount)
239 if (!isprint(*pszSubmount))
241 if (*pszSubmount == TEXT(' '))
243 if (*pszSubmount == TEXT('\t'))
252 * PIOCTL SUPPORT _____________________________________________________________
258 #include "../afsd/fs_utils.h"
260 #define __CM_CONFIG_INTERFACES_ONLY__
261 #include "../afsd/cm_config.h"
263 #define __CM_IOCTL_INTERFACES_ONLY__
264 #include "../afsd/cm_ioctl.h"
268 #define PIOCTL_MAXSIZE 2048
271 BOOL fCanIssuePIOCTL (void)
275 TCHAR szGateway[ 256 ] = TEXT("");
276 GetClientNetbiosName (szGateway);
277 return (szGateway[0]) ? TRUE : FALSE;
280 SERVICE_STATUS Status;
281 memset (&Status, 0x00, sizeof(Status));
282 Status.dwCurrentState = SERVICE_STOPPED;
285 if ((hManager = OpenSCManager (NULL, NULL, GENERIC_READ)) != NULL)
288 if ((hService = OpenService (hManager, TEXT("TransarcAFSDaemon"), GENERIC_READ)) != NULL)
290 QueryServiceStatus (hService, &Status);
291 CloseServiceHandle (hService);
294 CloseServiceHandle (hManager);
297 return (Status.dwCurrentState == SERVICE_RUNNING) ? TRUE : FALSE;
302 * QUERYDRIVEMAPLIST __________________________________________________________
306 void QueryDriveMapList_ReadSubmounts (PDRIVEMAPLIST pList)
310 size_t cchLHS = 1024;
311 LPTSTR mszLHS = AllocateStringMemory (cchLHS);
313 for (int iRetry = 0; iRetry < 5; ++iRetry)
315 DWORD rc = GetPrivateProfileString (cszSECTION_SUBMOUNTS, NULL, TEXT(""), mszLHS, cchLHS, cszINIFILE);
316 if ((rc != cchLHS-1) && (rc != cchLHS-2))
319 FreeStringMemory (mszLHS);
321 mszLHS = AllocateStringMemory (cchLHS);
324 for (LPTSTR psz = mszLHS; psz && *psz; psz += 1+lstrlen(psz))
327 memset (&Submount, 0x00, sizeof(SUBMOUNT));
328 lstrcpy (Submount.szSubmount, psz);
330 TCHAR szMapping[ MAX_PATH ] = TEXT("");
331 GetPrivateProfileString (cszSECTION_SUBMOUNTS, Submount.szSubmount, TEXT(""), szMapping, MAX_PATH, cszINIFILE);
332 if (szMapping[0] != TEXT('\0'))
334 AdjustAfsPath (Submount.szMapping, szMapping, FALSE, TRUE);
336 for (size_t ii = 0; ii < pList->cSubmounts; ++ii)
338 if (!pList->aSubmounts[ii].szSubmount[0])
341 if (REALLOC (pList->aSubmounts, pList->cSubmounts, 1+ii, cREALLOC_SUBMOUNTS))
343 memcpy (&pList->aSubmounts[ii], &Submount, sizeof(SUBMOUNT));
348 FreeStringMemory (mszLHS);
353 void QueryDriveMapList_ReadMappings (PDRIVEMAPLIST pList)
355 size_t cchLHS = 1024;
356 LPTSTR mszLHS = AllocateStringMemory (cchLHS);
358 for (int iRetry = 0; iRetry < 5; ++iRetry)
360 DWORD rc = GetPrivateProfileString (cszSECTION_MAPPINGS, NULL, TEXT(""), mszLHS, cchLHS, cszINIFILE);
361 if ((rc != cchLHS-1) && (rc != cchLHS-2))
364 FreeStringMemory (mszLHS);
366 mszLHS = AllocateStringMemory (cchLHS);
369 for (LPTSTR psz = mszLHS; psz && *psz; psz += 1+lstrlen(psz))
372 memset (&DriveMap, 0x00, sizeof(DRIVEMAP));
373 DriveMap.chDrive = toupper(*psz);
374 DriveMap.fPersistent = TRUE;
375 if ((DriveMap.chDrive < chDRIVE_A) || (DriveMap.chDrive > chDRIVE_Z))
378 TCHAR szMapping[ MAX_PATH ] = TEXT("");
379 GetPrivateProfileString (cszSECTION_MAPPINGS, psz, TEXT(""), szMapping, MAX_PATH, cszINIFILE);
380 if (szMapping[0] != TEXT('\0'))
382 AdjustAfsPath (DriveMap.szMapping, szMapping, TRUE, TRUE);
383 if (DriveMap.szMapping[ lstrlen(DriveMap.szMapping)-1 ] == TEXT('*'))
385 DriveMap.fPersistent = FALSE;
386 DriveMap.szMapping[ lstrlen(DriveMap.szMapping)-1 ] = TEXT('\0');
388 size_t iDrive = DriveMap.chDrive - chDRIVE_A;
389 memcpy (&pList->aDriveMap[ iDrive ], &DriveMap, sizeof(DRIVEMAP));
393 FreeStringMemory (mszLHS);
396 BOOL ForceMapActive (TCHAR chDrive)
401 szDrive[0] = chDrive;
404 GetPrivateProfileString (cszSECTION_ACTIVE, szDrive, TEXT("0"), szActive, sizeof(szActive), cszINIFILE);
406 if ( !lstrcmp(szActive,"1") || !lstrcmpi(szActive,"true") || !lstrcmpi(szActive,"on") || !lstrcmpi(szActive,"yes") )
412 void WriteActiveMap (TCHAR chDrive, BOOL on)
416 szDrive[0] = chDrive;
419 WritePrivateProfileString (cszSECTION_ACTIVE, szDrive, on ? "1" : "0", cszINIFILE);
422 void QueryDriveMapList_WriteMappings (PDRIVEMAPLIST pList)
424 WriteDriveMappings (pList);
428 void WriteDriveMappings (PDRIVEMAPLIST pList)
430 WritePrivateProfileString (cszSECTION_MAPPINGS, NULL, NULL, cszINIFILE);
432 for (size_t iDrive = 0; iDrive < 26; ++iDrive)
434 if (pList->aDriveMap[iDrive].szMapping[0] != TEXT('\0'))
436 TCHAR szLHS[] = TEXT("*");
437 szLHS[0] = pList->aDriveMap[iDrive].chDrive;
439 TCHAR szRHS[MAX_PATH];
440 AdjustAfsPath (szRHS, pList->aDriveMap[iDrive].szMapping, TRUE, TRUE);
441 if (!pList->aDriveMap[iDrive].fPersistent)
442 lstrcat (szRHS, TEXT("*"));
444 WritePrivateProfileString (cszSECTION_MAPPINGS, szLHS, szRHS, cszINIFILE);
449 BOOL DriveIsGlobalAfsDrive(TCHAR chDrive)
451 TCHAR szKeyName[128];
452 TCHAR szValueName[128];
456 _stprintf(szKeyName, TEXT("%s\\GlobalAutoMapper"), sAFSConfigKeyName);
458 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, szKeyName, 0, KEY_QUERY_VALUE, &hKey) != ERROR_SUCCESS)
461 _stprintf(szValueName, TEXT("%c:"), chDrive);
463 DWORD dwSize = sizeof(szValue);
464 BOOL bIsGlobal = (RegQueryValueEx (hKey, szValueName, NULL, NULL, (PBYTE)szValue, &dwSize) == ERROR_SUCCESS);
472 void QueryDriveMapList_FindNetworkDrives (PDRIVEMAPLIST pList, BOOL *pfFoundNew)
474 for (TCHAR chDrive = chDRIVE_A; chDrive <= chDRIVE_Z; ++chDrive)
476 TCHAR szSubmount[ MAX_PATH ];
477 if (!GetDriveSubmount (chDrive, szSubmount))
480 // We've got a mapping! Drive {chDrive} is mapped to submount
481 // {szSubmount}. See if that submount makes sense.
485 size_t iDrive = chDrive - chDRIVE_A;
486 if (pList->aDriveMap[ iDrive ].szMapping[0] != TEXT('\0'))
488 pList->aDriveMap[ iDrive ].fActive = TRUE;
489 lstrcpy (pList->aDriveMap[ iDrive ].szSubmount, szSubmount);
493 else // (IsWindowsNT())
495 TCHAR szAfsPath[ MAX_PATH ];
496 if (!SubmountToPath (pList, szAfsPath, szSubmount, TRUE))
499 // Okay, we know that drive {chDrive} is mapped to afs path {szAfsPath}.
500 // If this drive is a global afs drive, then reject it. Otherwise, look
501 // at pList->aDriveMap, to see if this drive mapping is already in our
502 // list. If not, add it and set pfFoundNew.
504 if (DriveIsGlobalAfsDrive(chDrive))
507 size_t iDrive = chDrive - chDRIVE_A;
508 if (lstrcmpi (pList->aDriveMap[ iDrive ].szMapping, szAfsPath))
511 pList->aDriveMap[ iDrive ].fPersistent = TRUE;
513 pList->aDriveMap[ iDrive ].fActive = TRUE;
514 pList->aDriveMap[ iDrive ].chDrive = chDrive;
515 lstrcpy (pList->aDriveMap[ iDrive ].szSubmount, szSubmount);
516 AdjustAfsPath (pList->aDriveMap[ iDrive ].szMapping, szAfsPath, TRUE, TRUE);
522 void QueryDriveMapList (PDRIVEMAPLIST pList)
524 // Initialize the data structure
526 memset (pList, 0x00, sizeof(DRIVEMAPLIST));
527 for (size_t ii = 0; ii < 26; ++ii)
528 pList->aDriveMap[ii].chDrive = chDRIVE_A + ii;
530 // Read the current lists of submounts and drive letter mappings
532 QueryDriveMapList_ReadSubmounts (pList);
533 QueryDriveMapList_ReadMappings (pList);
535 // Look through the current list of network drives, and see if
536 // any are currently mapped to AFS. If we find any which are mapped
537 // into AFS unexpectedly, we'll have to rewrite the mappings list.
539 BOOL fFoundNew = FALSE;
540 QueryDriveMapList_FindNetworkDrives (pList, &fFoundNew);
544 QueryDriveMapList_WriteMappings (pList);
549 void FreeDriveMapList (PDRIVEMAPLIST pList)
551 if (pList->aSubmounts)
552 Free (pList->aSubmounts);
553 memset (pList, 0x00, sizeof(DRIVEMAPLIST));
557 BOOL PathToSubmount (LPTSTR pszSubmount, LPTSTR pszMapping, LPTSTR pszSubmountReq, ULONG *pStatus)
559 if (pszSubmountReq && !IsValidSubmountName (pszSubmountReq))
560 pszSubmountReq = NULL;
562 TCHAR szAfsPath[ MAX_PATH ];
563 AdjustAfsPath (szAfsPath, pszMapping, TRUE, TRUE);
565 // Try to ask AFSD for a new submount name.
567 if (!fCanIssuePIOCTL())
570 BYTE InData[ PIOCTL_MAXSIZE ];
571 memset (InData, 0x00, sizeof(InData));
573 LPTSTR pszInData = (LPTSTR)InData;
574 lstrcpy (pszInData, pszMapping);
575 pszInData += 1+lstrlen(pszInData);
577 lstrcpy (pszInData, pszSubmountReq);
579 BYTE OutData[ PIOCTL_MAXSIZE ];
580 memset (OutData, 0x00, sizeof(OutData));
582 struct ViceIoctl IOInfo;
583 IOInfo.in = (char *)InData;
584 IOInfo.in_size = PIOCTL_MAXSIZE;
585 IOInfo.out = (char *)OutData;
586 IOInfo.out_size = PIOCTL_MAXSIZE;
588 ULONG status = pioctl (0, VIOC_MAKESUBMOUNT, &IOInfo, 1);
595 lstrcpy (pszSubmount, (LPCTSTR)OutData);
596 return (pszSubmount[0] != TEXT('\0')) ? TRUE : FALSE;
600 BOOL ActivateDriveMap (TCHAR chDrive, LPTSTR pszMapping, LPTSTR pszSubmountReq, BOOL fPersistent, DWORD *pdwStatus)
602 // We can only map drives to places in AFS using this function.
604 if ( (lstrncmpi (pszMapping, cm_slash_mount_root, lstrlen(cm_slash_mount_root))) &&
605 (lstrncmpi (pszMapping, cm_back_slash_mount_root, lstrlen(cm_back_slash_mount_root))) )
608 *pdwStatus = ERROR_BAD_NETPATH;
612 // First we have to translate {pszMapping} into a submount, and if there is
613 // no current submount associated with this path, we'll have to make one.
616 TCHAR szSubmount[ MAX_PATH ];
617 if (!PathToSubmount (szSubmount, pszMapping, pszSubmountReq, &status))
624 // We now have a submount name and drive letter--map the network drive.
626 TCHAR szClient[ MAX_PATH ];
627 GetClientNetbiosName (szClient);
629 TCHAR szLocal[ MAX_PATH ] = TEXT("*:");
630 szLocal[0] = chDrive;
632 TCHAR szRemote[ MAX_PATH ];
633 wsprintf (szRemote, TEXT("\\\\%s\\%s"), szClient, szSubmount);
635 DWORD rc=MountDOSDrive(chDrive,szSubmount,fPersistent);
645 BOOL InactivateDriveMap (TCHAR chDrive, DWORD *pdwStatus)
647 DWORD rc = DisMountDOSDrive(chDrive, FALSE);
657 void AddSubMount (LPTSTR pszSubmount, LPTSTR pszMapping)
659 TCHAR szRHS[ MAX_PATH ];
660 AdjustAfsPath (szRHS, pszMapping, FALSE, TRUE);
662 lstrcpy (szRHS, TEXT("/"));
663 WritePrivateProfileString (cszSECTION_SUBMOUNTS, pszSubmount, szRHS, cszINIFILE);
667 void RemoveSubMount (LPTSTR pszSubmount)
669 WritePrivateProfileString (cszSECTION_SUBMOUNTS, pszSubmount, NULL, cszINIFILE);
673 void AdjustAfsPath (LPTSTR pszTarget, LPCTSTR pszSource, BOOL fWantAFS, BOOL fWantForwardSlashes)
676 lstrcpy (pszTarget, (fWantAFS) ? cm_slash_mount_root : TEXT(""));
677 else if ((*pszSource != TEXT('/')) && (*pszSource != TEXT('\\')))
678 wsprintf (pszTarget, TEXT("%s/%s"),cm_slash_mount_root, pszSource);
679 // We don't want to strip afs off the start if it is part of something for example afscell.company.com
680 else if (fWantAFS && (lstrncmpi (&pszSource[1], cm_mount_root, strlen(cm_mount_root))) || !((pszSource[strlen(cm_slash_mount_root)] == TEXT('/')) ||
681 (pszSource[strlen(cm_slash_mount_root)] == TEXT('\\')) ||
682 (lstrlen(pszSource) == strlen(cm_slash_mount_root))))
683 wsprintf (pszTarget, TEXT("%s%s"),cm_slash_mount_root, pszSource);
684 else if (!fWantAFS && (!lstrncmpi (&pszSource[1], cm_mount_root, strlen(cm_mount_root)) && ((pszSource[strlen(cm_slash_mount_root)] == TEXT('/')) ||
685 (pszSource[strlen(cm_slash_mount_root)] == TEXT('\\')) ||
686 (lstrlen(pszSource) == strlen(cm_slash_mount_root)))))
687 lstrcpy (pszTarget, &pszSource[strlen(cm_slash_mount_root)]);
689 lstrcpy (pszTarget, pszSource);
691 for (LPTSTR pch = pszTarget; *pch; ++pch)
693 if (fWantForwardSlashes)
695 *pch = (*pch == TEXT('\\')) ? TEXT('/') : (*pch);
697 else // (!fWantForwardSlashes)
699 *pch = (*pch == TEXT('/')) ? TEXT('\\') : (*pch);
703 if (lstrlen(pszTarget) &&
704 ((pszTarget[lstrlen(pszTarget)-1] == TEXT('/')) ||
705 (pszTarget[lstrlen(pszTarget)-1] == TEXT('\\'))))
707 pszTarget[lstrlen(pszTarget)-1] = TEXT('\0');
711 BOOL GetDriveSubmount (TCHAR chDrive, LPTSTR pszSubmountNow)
713 TCHAR szDrive[] = TEXT("*:");
714 szDrive[0] = chDrive;
716 TCHAR szMapping[ _MAX_PATH ] = TEXT("");
717 LPTSTR pszSubmount = szMapping;
718 TCHAR szNetBiosName[32];
720 memset(szNetBiosName, '\0', sizeof(szNetBiosName));
721 lana_GetNetbiosName(szNetBiosName, LANA_NETBIOS_NAME_FULL);
722 _tcscat(szNetBiosName, TEXT("\\"));
726 if (!QueryDosDevice (szDrive, szMapping, MAX_PATH))
729 // Now if this is an AFS network drive mapping, {szMapping} will be:
731 // \Device\LanmanRedirector\<Drive>:\<netbiosname>\submount
733 // on Windows NT. On Windows 2000, it will be:
735 // \Device\LanmanRedirector\;<Drive>:0\<netbiosname>\submount
737 // (This is presumably to support multiple drive mappings with
740 // on Windows XP and 2003, it will be :
741 // \Device\LanmanRedirector\;<Drive>:<AuthID>\<netbiosname>\submount
743 // where : <Drive> : DOS drive letter
744 // <AuthID>: Authentication ID, 16 char hex.
745 // <netbiosname>: Netbios name of server
747 if (_tcsnicmp(szMapping, cszLANMANDEVICE, _tcslen(cszLANMANDEVICE)))
749 pszSubmount = &szMapping[ _tcslen(cszLANMANDEVICE) ];
753 if (*(pszSubmount) != TEXT(';'))
758 if (toupper(*(++pszSubmount)) != chDrive)
761 if (*(++pszSubmount) != TEXT(':'))
765 // No longer a safe assumption on XP
767 if (*(++pszSubmount) != TEXT('0'))
772 while (*(++pszSubmount) != TEXT('\\'))
778 // note that szNetBiosName has a '\\' tagged in the end earlier
779 for (++pszSubmount; *pszSubmount && (*pszSubmount != TEXT('\\')); ++pszSubmount)
780 if (!_tcsncicmp(pszSubmount, szNetBiosName, _tcslen(szNetBiosName)))
782 if ((!*pszSubmount) || (*pszSubmount == TEXT('\\')))
785 pszSubmount += _tcslen(szNetBiosName);
787 else // (!IsWindowsNT())
789 DWORD dwSize = MAX_PATH;
790 if (WNetGetConnection (szDrive, szMapping, &dwSize) != NO_ERROR)
792 if (*(pszSubmount++) != TEXT('\\'))
794 if (*(pszSubmount++) != TEXT('\\'))
796 for ( ; *pszSubmount && (*pszSubmount != TEXT('\\')); ++pszSubmount)
797 if (!lstrncmpi (pszSubmount, szNetBiosName, lstrlen(szNetBiosName)))
799 if ((!*pszSubmount) || (*pszSubmount == TEXT('\\')))
801 pszSubmount += lstrlen(szNetBiosName);
804 if (!pszSubmount || !*pszSubmount)
807 lstrcpy (pszSubmountNow, pszSubmount);
811 /* Generate Random User name random acording to time*/
813 TCHAR pUserName[MAXRANDOMNAMELEN]=TEXT("");
814 BOOL fUserName=FALSE;
815 #define AFSLogonOptionName TEXT("System\\CurrentControlSet\\Services\\TransarcAFSDaemon\\NetworkProvider")
817 void SetBitLogonOption(BOOL set,DWORD value)
820 RWLogonOption(FALSE,((set)?value | RWLogonOption(TRUE,0):RWLogonOption(TRUE,0) & ~value) );
823 DWORD RWLogonOption(BOOL read,DWORD value)
825 // if read is true then if value==0 return registry value
826 // if read and value!=0 then use value to test registry, return TRUE if value bits match value read
829 DWORD LSPtype, LSPsize;
834 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, AFSLogonOptionName,0, KEY_QUERY_VALUE, &hk)==ERROR_SUCCESS)
836 LSPsize=sizeof(rval);
837 RegQueryValueEx(hk, "LogonOptions", NULL,
838 &LSPtype, (LPBYTE)&rval, &LSPsize);
841 return (value==0)?rval:((rval & value)==value);
844 if (RegCreateKeyEx (HKEY_LOCAL_MACHINE, AFSLogonOptionName, 0, NULL, 0, KEY_SET_VALUE, NULL, &hk, &dwDisp) == ERROR_SUCCESS)
846 RegSetValueEx(hk,TEXT("LogonOptions"),NULL,REG_DWORD,(LPBYTE)&value,sizeof(value));
853 void MapShareName(char *pszCmdLineA)
858 while (*pszCmdLineA && (*pszCmdLineA != ' '))
864 void GenRandomName(TCHAR *pname,int len)
867 { //user name was passed through command line, use once
871 srand( (unsigned)time( NULL ) );
872 for (int i=0;i<len;i++)
873 pname[i]='a'+(rand() % 26);
879 Make a connection using users name
880 if fUserName then force a connection
883 BOOL TestAndDoMapShare(DWORD dwState)
885 if ((dwState!=SERVICE_RUNNING) || (dwOldState!=SERVICE_START_PENDING))
890 dwOldState=SERVICE_RUNNING;
891 if (RWLogonOption(TRUE,LOGON_OPTION_HIGHSECURITY))
892 return (DoMapShare() && GlobalMountDrive());
893 return GlobalMountDrive();
896 BOOL IsServiceActive()
899 SERVICE_STATUS Status;
900 if ((hManager = OpenSCManager (NULL, NULL, GENERIC_READ)) != NULL)
903 if ((hService = OpenService (hManager, TEXT("TransarcAFSDaemon"), GENERIC_READ)) != NULL)
905 QueryServiceStatus (hService, &Status);
906 CloseServiceHandle (hService);
909 CloseServiceHandle (hManager);
912 return (Status.dwCurrentState == SERVICE_RUNNING) ? TRUE : FALSE;
915 void TestAndDoUnMapShare()
917 if (!RWLogonOption(TRUE,LOGON_OPTION_HIGHSECURITY))
922 void DoUnMapShare(BOOL drivemap) //disconnect drivemap
924 TCHAR szMachine[MAX_PATH],szPath[MAX_PATH];
927 LPNETRESOURCE lpnrLocal,lpnr=NULL;
929 DWORD cbBuffer=16384;
933 memset(szMachine, '\0', sizeof(szMachine));
934 lana_GetNetbiosName(szMachine, LANA_NETBIOS_NAME_FULL);
936 // Initialize the data structure
937 if ((res=WNetOpenEnum(RESOURCE_CONNECTED,RESOURCETYPE_DISK,RESOURCEUSAGE_CONNECTABLE,lpnr,&hEnum))!=NO_ERROR)
939 sprintf(szPath,"\\\\%s\\",szMachine);
941 lpnrLocal=(LPNETRESOURCE) GlobalAlloc(GPTR,cbBuffer);
943 memset(lpnrLocal,0,cbBuffer);
944 if ((res = WNetEnumResource(hEnum,&cEntries,lpnrLocal,&cbBuffer))==NO_ERROR)
946 for (DWORD i=0;i<cEntries;i++)
948 if (strstr(_strlwr(lpnrLocal[i].lpRemoteName),szPath))
950 if ((lpnrLocal[i].lpLocalName) && (strlen(lpnrLocal[i].lpLocalName)>0))
953 DisMountDOSDrive(*lpnrLocal[i].lpLocalName);
955 DisMountDOSDriveFull(lpnrLocal[i].lpRemoteName);
956 DEBUG_EVENT1("AFS DriveUnMap","UnMap-Remote=%x",res);
960 } while (res!=ERROR_NO_MORE_ITEMS);
961 GlobalFree((HGLOBAL)lpnrLocal);
962 WNetCloseEnum(hEnum);
965 BOOL DoMapShareChange()
968 TCHAR szMachine[ MAX_PATH],szPath[MAX_PATH];
971 LPNETRESOURCE lpnrLocal,lpnr=NULL;
974 DWORD cbBuffer=16384;
976 memset(szMachine, '\0', sizeof(szMachine));
977 lana_GetNetbiosName(szMachine, LANA_NETBIOS_NAME_FULL);
979 // Initialize the data structure
980 if (!IsServiceActive())
982 memset (&List, 0x00, sizeof(DRIVEMAPLIST));
983 for (size_t ii = 0; ii < 26; ++ii)
984 List.aDriveMap[ii].chDrive = chDRIVE_A + ii;
985 QueryDriveMapList_ReadSubmounts (&List);
986 if ((res=WNetOpenEnum(RESOURCE_CONNECTED,RESOURCETYPE_DISK,RESOURCEUSAGE_CONNECTABLE,lpnr,&hEnum))!=NO_ERROR)
988 lpnrLocal=(LPNETRESOURCE) GlobalAlloc(GPTR,cbBuffer);
989 sprintf(szPath,"\\\\%s\\",szMachine);
992 memset(lpnrLocal,0,cbBuffer);
993 if ((res = WNetEnumResource(hEnum,&cEntries,lpnrLocal,&cbBuffer))==NO_ERROR)
995 for (DWORD i=0;i<cEntries;i++)
997 if (strstr(_strlwr(lpnrLocal[i].lpRemoteName),szPath)==NULL)
998 continue; //only look at real afs mappings
999 CHAR * pSubmount=strrchr(lpnrLocal[i].lpRemoteName,'\\')+1;
1000 if (lstrcmpi(pSubmount,"all")==0)
1001 continue; // do not remove 'all'
1002 for (DWORD j=0;j<List.cSubmounts;j++)
1005 (List.aSubmounts[j].szSubmount[0]) &&
1006 (lstrcmpi(List.aSubmounts[j].szSubmount,pSubmount)==0)
1009 List.aSubmounts[j].fInUse=TRUE;
1013 // wasn't on list so lets remove
1014 DisMountDOSDrive(pSubmount);
1018 } while (res!=ERROR_NO_MORE_ITEMS);
1019 GlobalFree((HGLOBAL)lpnrLocal);
1020 WNetCloseEnum(hEnum);
1021 sprintf(szPath,"\\\\%s\\all",szMachine);
1023 // Lets connect all submounts that weren't connectd
1024 DWORD cbUser=MAXRANDOMNAMELEN-1;
1025 CHAR szUser[MAXRANDOMNAMELEN];
1026 CHAR * pUser = NULL;
1027 if (WNetGetUser(szPath,(LPSTR)szUser,&cbUser)!=NO_ERROR) {
1028 if (RWLogonOption(TRUE,LOGON_OPTION_HIGHSECURITY)) {
1029 if (!pUserName[0]) {
1030 GenRandomName(szUser,MAXRANDOMNAMELEN-1);
1037 if ((pUser=strchr(szUser,'\\'))!=NULL)
1041 for (DWORD j=0;j<List.cSubmounts;j++)
1043 if (List.aSubmounts[j].fInUse)
1045 DWORD res=MountDOSDrive(0,List.aSubmounts[j].szSubmount,FALSE,pUser);
1054 BOOL bMappedAll=FALSE;
1056 // Initialize the data structure
1057 DEBUG_EVENT0("AFS DoMapShare");
1058 QueryDriveMapList (&List);
1060 // All connections have been removed
1061 // Lets restore them after making the connection from the random name
1063 TCHAR szMachine[ MAX_PATH],szPath[MAX_PATH];
1064 memset(szMachine, '\0', sizeof(szMachine));
1065 lana_GetNetbiosName(szMachine, LANA_NETBIOS_NAME_FULL);
1066 sprintf(szPath,"\\\\%s\\all",szMachine);
1068 // Lets connect all submounts that weren't connectd
1069 DWORD cbUser=MAXRANDOMNAMELEN-1;
1070 CHAR szUser[MAXRANDOMNAMELEN];
1071 CHAR * pUser = NULL;
1072 if (WNetGetUser(szPath,(LPSTR)szUser,&cbUser)!=NO_ERROR) {
1073 if (RWLogonOption(TRUE,LOGON_OPTION_HIGHSECURITY)) {
1074 if (!pUserName[0]) {
1075 GenRandomName(szUser,MAXRANDOMNAMELEN-1);
1082 if ((pUser=strchr(szUser,'\\'))!=NULL)
1086 for (DWORD i=0;i<List.cSubmounts;i++)
1088 if (List.aSubmounts[i].szSubmount[0])
1090 DWORD res=MountDOSDrive(0,List.aSubmounts[i].szSubmount,FALSE,pUser);
1091 if (lstrcmpi("all",List.aSubmounts[i].szSubmount)==0)
1095 if (!bMappedAll) //make sure all is mapped also
1097 DWORD res=MountDOSDrive(0,"all",FALSE,pUser);
1098 if (res==ERROR_SESSION_CREDENTIAL_CONFLICT)
1100 DisMountDOSDrive("all");
1101 MountDOSDrive(0,"all",FALSE,pUser);
1104 for (TCHAR chDrive = chDRIVE_A; chDrive <= chDRIVE_Z; ++chDrive)
1106 if (List.aDriveMap[chDrive-chDRIVE_A].fActive ||
1107 ForceMapActive(chDrive))
1109 TCHAR szSubmount[ MAX_PATH ];
1110 if (List.aDriveMap[chDrive-chDRIVE_A].szSubmount[0])
1111 lstrcpy(szSubmount,List.aDriveMap[chDrive-chDRIVE_A].szSubmount);
1112 else if (!PathToSubmount (szSubmount, List.aDriveMap[chDrive-chDRIVE_A].szMapping, NULL, NULL))
1115 BOOL fPersistent = List.aDriveMap[chDrive-chDRIVE_A].fPersistent;
1116 if (RWLogonOption(TRUE,LOGON_OPTION_HIGHSECURITY))
1117 fPersistent = FALSE;
1118 DWORD res=MountDOSDrive(chDrive
1120 ,fPersistent,pUser);
1126 BOOL GlobalMountDrive()
1128 char szDriveToMapTo[5];
1130 char szKeyName[256];
1134 DWORD dwSubMountSize;
1135 char unsigned szSubMount[256];
1136 char cm_HostName[200];
1137 DWORD dwType=sizeof(cm_HostName);
1138 if (!IsServiceActive())
1140 if (!GetComputerName(cm_HostName, &dwType))
1142 sprintf(szKeyName, "%s\\GlobalAutoMapper", sAFSConfigKeyName);
1144 dwResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE, szKeyName, 0, KEY_QUERY_VALUE,
1146 if (dwResult != ERROR_SUCCESS)
1150 dwDriveSize = sizeof(szDriveToMapTo);
1151 dwSubMountSize = sizeof(szSubMount);
1152 dwResult = RegEnumValue(hKey, dwIndex++, szDriveToMapTo, &dwDriveSize,
1153 0, &dwType, szSubMount, &dwSubMountSize);
1154 if (dwResult != ERROR_MORE_DATA) {
1155 if (dwResult != ERROR_SUCCESS) {
1156 if (dwResult != ERROR_NO_MORE_ITEMS)
1158 DEBUG_EVENT1("AFS DriveMap","Failed to read GlobalAutoMapper values: %d",dwResult);
1163 dwResult=MountDOSDrive(*szDriveToMapTo,(const char *)szSubMount,FALSE);
1169 DWORD MountDOSDrive(char chDrive,const char *szSubmount,BOOL bPersistent,const char * pUsername)
1171 TCHAR szPath[MAX_PATH];
1172 TCHAR szClient[MAX_PATH];
1173 TCHAR szDrive[3] = TEXT("?:");
1174 sprintf(szDrive,"%c:",chDrive);
1175 GetClientNetbiosName (szClient);
1176 sprintf(szPath,"\\\\%s\\%s",szClient,szSubmount);
1178 memset (&nr, 0x00, sizeof(NETRESOURCE));
1179 nr.dwType=RESOURCETYPE_DISK;
1180 nr.lpLocalName=szDrive;
1181 nr.lpRemoteName=szPath;
1182 nr.dwDisplayType = RESOURCEDISPLAYTYPE_SHARE;
1183 DWORD res=WNetAddConnection2(&nr,NULL,pUsername,(bPersistent)?CONNECT_UPDATE_PROFILE:0);
1184 DEBUG_EVENT5("AFS DriveMap","Mount %s Local[%s] Remote[%s] User[%s]=%x",
1185 (bPersistent)?"Persistant" : "NonPresistant",
1186 szDrive,szPath,pUsername?pUsername:"NULL",res);
1190 DWORD DisMountDOSDriveFull(const char *szPath,BOOL bForce)
1192 DWORD res=WNetCancelConnection(szPath,bForce);
1193 DEBUG_EVENT3("AFS DriveMap","%sDismount Remote[%s]=%x",
1194 bForce ? "Forced " : "",szPath,res);
1195 return (res==ERROR_NOT_CONNECTED)?NO_ERROR:res;
1198 DWORD DisMountDOSDrive(const char *pSubmount,BOOL bForce)
1200 TCHAR szPath[MAX_PATH];
1201 TCHAR szClient[MAX_PATH];
1202 GetClientNetbiosName (szClient);
1203 sprintf(szPath,"\\\\%s\\%s",szClient,pSubmount);
1204 return DisMountDOSDriveFull(szPath,bForce);
1208 DWORD DisMountDOSDrive(const char chDrive,BOOL bForce)
1210 TCHAR szPath[MAX_PATH];
1211 sprintf(szPath,"%c:",chDrive);
1212 return DisMountDOSDriveFull(szPath,bForce);