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>
18 #include <WINNT/TaLocale.h>
25 * REGISTRY ___________________________________________________________________
29 #undef AFSConfigKeyName
30 const TCHAR sAFSConfigKeyName[] = TEXT("SYSTEM\\CurrentControlSet\\Services\\TransarcAFSDaemon\\Parameters");
34 * PROFILE SECTIONS ___________________________________________________________
38 #define cREALLOC_SUBMOUNTS 4
40 static TCHAR cszINIFILE[] = TEXT("afsdsbmt.ini");
41 static TCHAR cszSECTION_SUBMOUNTS[] = TEXT("AFS Submounts");
42 static TCHAR cszSECTION_MAPPINGS[] = TEXT("AFS Mappings");
44 static TCHAR cszAUTOSUBMOUNT[] = TEXT("Auto");
45 static TCHAR cszLANMANDEVICE[] = TEXT("\\Device\\LanmanRedirector\\");
49 * STRINGS ____________________________________________________________________
53 static LPTSTR AllocateStringMemory (size_t cch)
55 LPTSTR psz = (LPTSTR)Allocate (sizeof(TCHAR) * (cch+1));
56 memset (psz, 0x00, sizeof(TCHAR) * (cch+1));
60 static void FreeStringMemory (LPTSTR pszString)
65 static int lstrncmpi (LPCTSTR pszA, LPCTSTR pszB, size_t cch)
69 return (!pszB) - (!pszA); // A,!B:1, !A,B:-1, !A,!B:0
72 for ( ; cch > 0; cch--, pszA = CharNext(pszA), pszB = CharNext(pszB))
74 TCHAR chA = toupper( *pszA );
75 TCHAR chB = toupper( *pszB );
78 return (!chB) - (!chA); // A,!B:1, !A,B:-1, !A,!B:0
81 return (int)(chA) - (int)(chB); // -1:A<B, 0:A==B, 1:A>B
84 return 0; // no differences before told to stop comparing, so A==B
89 * REALLOC ____________________________________________________________________
94 #define REALLOC(_a,_c,_r,_i) DriveMapReallocFunction ((LPVOID*)&_a,sizeof(*_a),&_c,_r,_i)
95 BOOL DriveMapReallocFunction (LPVOID *ppTarget, size_t cbElement, size_t *pcTarget, size_t cReq, size_t cInc)
100 if (cReq <= *pcTarget)
103 if ((cNew = cInc * ((cReq + cInc-1) / cInc)) <= 0)
106 if ((pNew = Allocate (cbElement * cNew)) == NULL)
108 memset (pNew, 0x00, cbElement * cNew);
112 memcpy (pNew, *ppTarget, cbElement * (*pcTarget));
124 * WINDOWS NT STUFF ___________________________________________________________
128 static BOOL IsWindowsNT (void)
130 static BOOL fChecked = FALSE;
131 static BOOL fIsWinNT = FALSE;
137 OSVERSIONINFO Version;
138 memset (&Version, 0x00, sizeof(Version));
139 Version.dwOSVersionInfoSize = sizeof(Version);
141 if (GetVersionEx (&Version))
143 if (Version.dwPlatformId == VER_PLATFORM_WIN32_NT)
152 BOOL IsWindows2000 (void)
154 static BOOL fChecked = FALSE;
155 static BOOL fIsWin2K = FALSE;
161 OSVERSIONINFO Version;
162 memset (&Version, 0x00, sizeof(Version));
163 Version.dwOSVersionInfoSize = sizeof(Version);
165 if (GetVersionEx (&Version))
167 if (Version.dwPlatformId == VER_PLATFORM_WIN32_NT &&
168 Version.dwMajorVersion >= 5)
177 * GENERAL ____________________________________________________________________
181 void GetClientNetbiosName (LPTSTR pszName)
183 *pszName = TEXT('\0');
188 if (RegOpenKey (HKEY_LOCAL_MACHINE, TEXT("System\\CurrentControlSet\\Control\\ComputerName\\ComputerName"), &hk) == 0)
190 DWORD dwSize = MAX_PATH;
191 DWORD dwType = REG_SZ;
192 RegQueryValueEx (hk, TEXT("ComputerName"), NULL, &dwType, (PBYTE)pszName, &dwSize);
195 else // (!IsWindowsNT())
198 if (RegOpenKey (HKEY_LOCAL_MACHINE, TEXT("System\\CurrentControlSet\\Services\\TransarcAFSDaemon\\Parameters"), &hk) == 0)
200 DWORD dwSize = MAX_PATH;
201 DWORD dwType = REG_SZ;
202 RegQueryValueEx (hk, TEXT("Gateway"), NULL, &dwType, (PBYTE)pszName, &dwSize);
206 // Shorten the server name from its FQDN
208 for (LPTSTR pch = pszName; *pch; ++pch)
210 if (*pch == TEXT('.'))
212 *(LPTSTR)pch = TEXT('\0');
217 // Form NetBIOS name from client's (possibly truncated) simple host name.
218 if (*pszName != TEXT('\0')) {
219 pszName[11] = TEXT('\0');
220 lstrcat(pszName, TEXT("-AFS"));
225 BOOL SubmountToPath (PDRIVEMAPLIST pList, LPTSTR pszPath, LPTSTR pszSubmount, BOOL fMarkInUse)
227 // We can't do this translation unless we're under Windows NT.
232 // \\computer-afs\all always maps to "/afs"
234 if (!lstrcmpi (pszSubmount, TEXT("all")))
236 lstrcpy (pszPath, TEXT("/afs"));
240 // Otherwise, look up our list of submounts.
242 for (size_t ii = 0; ii < pList->cSubmounts; ++ii)
244 if (!lstrcmpi (pList->aSubmounts[ii].szSubmount, pszSubmount))
247 pList->aSubmounts[ii].fInUse = TRUE;
248 AdjustAfsPath (pszPath, pList->aSubmounts[ii].szMapping, TRUE, TRUE);
257 BOOL IsValidSubmountName (LPTSTR pszSubmount)
261 if (lstrlen (pszSubmount) > 12)
264 for ( ; *pszSubmount; ++pszSubmount)
266 if (!isprint(*pszSubmount))
268 if (*pszSubmount == TEXT(' '))
270 if (*pszSubmount == TEXT('\t'))
279 * PIOCTL SUPPORT _____________________________________________________________
285 #include "../afsd/fs_utils.h"
287 #define __CM_CONFIG_INTERFACES_ONLY__
288 #include "../afsd/cm_config.h"
290 #define __CM_IOCTL_INTERFACES_ONLY__
291 #include "../afsd/cm_ioctl.h"
295 #define PIOCTL_MAXSIZE 2048
298 BOOL fCanIssuePIOCTL (void)
302 TCHAR szGateway[ 256 ] = TEXT("");
303 GetClientNetbiosName (szGateway);
304 return (szGateway[0]) ? TRUE : FALSE;
307 SERVICE_STATUS Status;
308 memset (&Status, 0x00, sizeof(Status));
309 Status.dwCurrentState = SERVICE_STOPPED;
312 if ((hManager = OpenSCManager (NULL, NULL, GENERIC_READ)) != NULL)
315 if ((hService = OpenService (hManager, TEXT("TransarcAFSDaemon"), GENERIC_READ)) != NULL)
317 QueryServiceStatus (hService, &Status);
318 CloseServiceHandle (hService);
321 CloseServiceHandle (hManager);
324 return (Status.dwCurrentState == SERVICE_RUNNING) ? TRUE : FALSE;
329 * QUERYDRIVEMAPLIST __________________________________________________________
333 void QueryDriveMapList_ReadSubmounts (PDRIVEMAPLIST pList)
337 size_t cchLHS = 1024;
338 LPTSTR mszLHS = AllocateStringMemory (cchLHS);
340 for (int iRetry = 0; iRetry < 5; ++iRetry)
342 DWORD rc = GetPrivateProfileString (cszSECTION_SUBMOUNTS, NULL, TEXT(""), mszLHS, cchLHS, cszINIFILE);
343 if ((rc != cchLHS-1) && (rc != cchLHS-2))
346 FreeStringMemory (mszLHS);
348 mszLHS = AllocateStringMemory (cchLHS);
351 for (LPTSTR psz = mszLHS; psz && *psz; psz += 1+lstrlen(psz))
354 memset (&Submount, 0x00, sizeof(SUBMOUNT));
355 lstrcpy (Submount.szSubmount, psz);
357 TCHAR szMapping[ MAX_PATH ] = TEXT("");
358 GetPrivateProfileString (cszSECTION_SUBMOUNTS, Submount.szSubmount, TEXT(""), szMapping, MAX_PATH, cszINIFILE);
359 if (szMapping[0] != TEXT('\0'))
361 AdjustAfsPath (Submount.szMapping, szMapping, FALSE, TRUE);
363 for (size_t ii = 0; ii < pList->cSubmounts; ++ii)
365 if (!pList->aSubmounts[ii].szSubmount[0])
368 if (REALLOC (pList->aSubmounts, pList->cSubmounts, 1+ii, cREALLOC_SUBMOUNTS))
370 memcpy (&pList->aSubmounts[ii], &Submount, sizeof(SUBMOUNT));
375 FreeStringMemory (mszLHS);
380 void QueryDriveMapList_ReadMappings (PDRIVEMAPLIST pList)
382 size_t cchLHS = 1024;
383 LPTSTR mszLHS = AllocateStringMemory (cchLHS);
385 for (int iRetry = 0; iRetry < 5; ++iRetry)
387 DWORD rc = GetPrivateProfileString (cszSECTION_MAPPINGS, NULL, TEXT(""), mszLHS, cchLHS, cszINIFILE);
388 if ((rc != cchLHS-1) && (rc != cchLHS-2))
391 FreeStringMemory (mszLHS);
393 mszLHS = AllocateStringMemory (cchLHS);
396 for (LPTSTR psz = mszLHS; psz && *psz; psz += 1+lstrlen(psz))
399 memset (&DriveMap, 0x00, sizeof(DRIVEMAP));
400 DriveMap.chDrive = toupper(*psz);
401 DriveMap.fPersistent = TRUE;
402 if ((DriveMap.chDrive < chDRIVE_A) || (DriveMap.chDrive > chDRIVE_Z))
405 TCHAR szMapping[ MAX_PATH ] = TEXT("");
406 GetPrivateProfileString (cszSECTION_MAPPINGS, psz, TEXT(""), szMapping, MAX_PATH, cszINIFILE);
407 if (szMapping[0] != TEXT('\0'))
409 AdjustAfsPath (DriveMap.szMapping, szMapping, TRUE, TRUE);
410 if (DriveMap.szMapping[ lstrlen(DriveMap.szMapping)-1 ] == TEXT('*'))
412 DriveMap.fPersistent = FALSE;
413 DriveMap.szMapping[ lstrlen(DriveMap.szMapping)-1 ] = TEXT('\0');
415 size_t iDrive = DriveMap.chDrive - chDRIVE_A;
416 memcpy (&pList->aDriveMap[ iDrive ], &DriveMap, sizeof(DRIVEMAP));
420 FreeStringMemory (mszLHS);
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;
591 if ((status = pioctl (0, VIOC_MAKESUBMOUNT, &IOInfo, 1)) != 0)
594 lstrcpy (pszSubmount, (LPCTSTR)OutData);
595 return (pszSubmount[0] != TEXT('\0')) ? TRUE : FALSE;
599 BOOL ActivateDriveMap (TCHAR chDrive, LPTSTR pszMapping, LPTSTR pszSubmountReq, BOOL fPersistent, DWORD *pdwStatus)
601 // We can only map drives to places in AFS using this function.
603 if ( (lstrncmpi (pszMapping, TEXT("/afs"), lstrlen(TEXT("/afs")))) &&
604 (lstrncmpi (pszMapping, TEXT("\\afs"), lstrlen(TEXT("\\afs")))) )
607 *pdwStatus = ERROR_BAD_NETPATH;
611 // First we have to translate {pszMapping} into a submount, and if there is
612 // no current submount associated with this path, we'll have to make one.
615 TCHAR szSubmount[ MAX_PATH ];
616 if (!PathToSubmount (szSubmount, pszMapping, pszSubmountReq, &status))
623 // We now have a submount name and drive letter--map the network drive.
625 TCHAR szClient[ MAX_PATH ];
626 GetClientNetbiosName (szClient);
628 TCHAR szLocal[ MAX_PATH ] = TEXT("*:");
629 szLocal[0] = chDrive;
631 TCHAR szRemote[ MAX_PATH ];
632 wsprintf (szRemote, TEXT("\\\\%s\\%s"), szClient, szSubmount);
634 NETRESOURCE Resource;
635 memset (&Resource, 0x00, sizeof(NETRESOURCE));
636 Resource.dwScope = RESOURCE_GLOBALNET;
637 Resource.dwType = RESOURCETYPE_DISK;
638 Resource.dwDisplayType = RESOURCEDISPLAYTYPE_SHARE;
639 Resource.dwUsage = RESOURCEUSAGE_CONNECTABLE;
640 Resource.lpLocalName = szLocal;
641 Resource.lpRemoteName = szRemote;
643 // DWORD rc = WNetAddConnection2 (&Resource, NULL, NULL, ((fPersistent) ? CONNECT_UPDATE_PROFILE : 0));
644 DWORD rc=MountDOSDrive(chDrive,szSubmount,fPersistent);
654 BOOL InactivateDriveMap (TCHAR chDrive, DWORD *pdwStatus)
656 DWORD rc = DisMountDOSDrive(chDrive, FALSE);
666 void AddSubMount (LPTSTR pszSubmount, LPTSTR pszMapping)
668 TCHAR szRHS[ MAX_PATH ];
669 AdjustAfsPath (szRHS, pszMapping, FALSE, TRUE);
671 lstrcpy (szRHS, TEXT("/"));
672 WritePrivateProfileString (cszSECTION_SUBMOUNTS, pszSubmount, szRHS, cszINIFILE);
676 void RemoveSubMount (LPTSTR pszSubmount)
678 WritePrivateProfileString (cszSECTION_SUBMOUNTS, pszSubmount, NULL, cszINIFILE);
682 void AdjustAfsPath (LPTSTR pszTarget, LPCTSTR pszSource, BOOL fWantAFS, BOOL fWantForwardSlashes)
685 lstrcpy (pszTarget, (fWantAFS) ? TEXT("/afs") : TEXT(""));
686 else if ((*pszSource != TEXT('/')) && (*pszSource != TEXT('\\')))
687 wsprintf (pszTarget, TEXT("/afs/%s"), pszSource);
688 // We don't want to strip afs off the start if it is part of something for example afscell.company.com
689 else if (fWantAFS && (lstrncmpi (&pszSource[1], TEXT("afs"), 3)) || !((pszSource[4] == TEXT('/')) ||
690 (pszSource[4] == TEXT('\\')) ||
691 (lstrlen(pszSource) == 4)))
692 wsprintf (pszTarget, TEXT("/afs%s"), pszSource);
693 else if (!fWantAFS && (!lstrncmpi (&pszSource[1], TEXT("afs"), 3) && ((pszSource[4] == TEXT('/')) ||
694 (pszSource[4] == TEXT('\\')) ||
695 (lstrlen(pszSource) == 4))))
696 lstrcpy (pszTarget, &pszSource[4]);
698 lstrcpy (pszTarget, pszSource);
700 for (LPTSTR pch = pszTarget; *pch; ++pch)
702 if (fWantForwardSlashes)
704 *pch = (*pch == TEXT('\\')) ? TEXT('/') : (*pch);
706 else // (!fWantForwardSlashes)
708 *pch = (*pch == TEXT('/')) ? TEXT('\\') : (*pch);
712 if (lstrlen(pszTarget) &&
713 ((pszTarget[lstrlen(pszTarget)-1] == TEXT('/')) ||
714 (pszTarget[lstrlen(pszTarget)-1] == TEXT('\\'))))
716 pszTarget[lstrlen(pszTarget)-1] = TEXT('\0');
721 BOOL GetDriveSubmount (TCHAR chDrive, LPTSTR pszSubmountNow)
723 TCHAR szDrive[] = TEXT("*:");
724 szDrive[0] = chDrive;
726 TCHAR szMapping[ MAX_PATH ] = TEXT("");
727 LPTSTR pszSubmount = szMapping;
731 QueryDosDevice (szDrive, szMapping, MAX_PATH);
733 // Now if this is an AFS network drive mapping, {szMapping} will be:
735 // \Device\LanmanRedirector\Q:\machine-afs\submount
737 // on Windows NT. On Windows 2000, it will be:
739 // \Device\LanmanRedirector\;Q:0\machine-afs\submount
741 // (This is presumably to support multiple drive mappings with
744 if (lstrncmpi (szMapping, cszLANMANDEVICE, lstrlen(cszLANMANDEVICE)))
746 pszSubmount = &szMapping[ lstrlen(cszLANMANDEVICE) ];
750 if (*(pszSubmount) != TEXT(';'))
755 if (toupper(*(++pszSubmount)) != chDrive)
758 if (*(++pszSubmount) != TEXT(':'))
762 if (*(++pszSubmount) != TEXT('0'))
766 while (*(++pszSubmount) != TEXT('\\'))
771 for (++pszSubmount; *pszSubmount && (*pszSubmount != TEXT('\\')); ++pszSubmount)
772 if (!lstrncmpi (pszSubmount, TEXT("-afs\\"), lstrlen(TEXT("-afs\\"))))
774 if ((!*pszSubmount) || (*pszSubmount == TEXT('\\')))
776 pszSubmount += lstrlen("-afs\\");
778 else // (!IsWindowsNT())
780 DWORD dwSize = MAX_PATH;
781 if (WNetGetConnection (szDrive, szMapping, &dwSize) != NO_ERROR)
783 if (*(pszSubmount++) != TEXT('\\'))
785 if (*(pszSubmount++) != TEXT('\\'))
787 for ( ; *pszSubmount && (*pszSubmount != TEXT('\\')); ++pszSubmount)
788 if (!lstrncmpi (pszSubmount, TEXT("-afs\\"), lstrlen(TEXT("-afs\\"))))
790 if ((!*pszSubmount) || (*pszSubmount == TEXT('\\')))
792 pszSubmount += lstrlen("-afs\\");
795 if (!pszSubmount || !*pszSubmount)
798 lstrcpy (pszSubmountNow, pszSubmount);
802 /* Generate Random User name random acording to time*/
804 TCHAR pUserName[MAXRANDOMNAMELEN];
805 BOOL fUserName=FALSE;
806 #define AFSLogonOptionName TEXT("System\\CurrentControlSet\\Services\\TransarcAFSDaemon\\NetworkProvider")
808 void SetBitLogonOption(BOOL set,DWORD value)
811 RWLogonOption(FALSE,((set)?value | RWLogonOption(TRUE,0):RWLogonOption(TRUE,0) & ~value) );
814 DWORD RWLogonOption(BOOL read,DWORD value)
816 // if read is true then if value==0 return registry value
817 // if read and value!=0 then use value to test registry, return TRUE if value bits match value read
820 DWORD LSPtype, LSPsize;
825 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, AFSLogonOptionName,0, KEY_QUERY_VALUE, &hk)==ERROR_SUCCESS)
827 LSPsize=sizeof(rval);
828 RegQueryValueEx(hk, "LogonOptions", NULL,
829 &LSPtype, (LPBYTE)&rval, &LSPsize);
832 return (value==0)?rval:((rval & value)==value);
835 if (RegCreateKeyEx (HKEY_LOCAL_MACHINE, AFSLogonOptionName, 0, NULL, 0, KEY_SET_VALUE, NULL, &hk, &dwDisp) == ERROR_SUCCESS)
837 RegSetValueEx(hk,TEXT("LogonOptions"),NULL,REG_DWORD,(LPBYTE)&value,sizeof(value));
844 void MapShareName(char *pszCmdLineA)
849 while (*pszCmdLineA && (*pszCmdLineA != ' '))
855 void GenRandomName(TCHAR *pname,int len)
858 { //user name was passed through command line, use once
862 srand( (unsigned)time( NULL ) );
863 for (int i=0;i<len;i++)
864 pname[i]='a'+(rand() % 26);
870 Make a connection using users name
871 if fUserName then force a connection
874 BOOL TestAndDoMapShare(DWORD dwState)
876 if ((dwState!=SERVICE_RUNNING) || (dwOldState!=SERVICE_START_PENDING))
881 dwOldState=SERVICE_RUNNING;
882 if (RWLogonOption(TRUE,LOGON_OPTION_HIGHSECURITY))
883 return (DoMapShare() && GlobalMountDrive());
884 return GlobalMountDrive();
887 BOOL IsServiceActive()
890 SERVICE_STATUS Status;
891 if ((hManager = OpenSCManager (NULL, NULL, GENERIC_READ)) != NULL)
894 if ((hService = OpenService (hManager, TEXT("TransarcAFSDaemon"), GENERIC_READ)) != NULL)
896 QueryServiceStatus (hService, &Status);
897 CloseServiceHandle (hService);
900 CloseServiceHandle (hManager);
903 return (Status.dwCurrentState == SERVICE_RUNNING) ? TRUE : FALSE;
906 void TestAndDoUnMapShare()
908 if (!RWLogonOption(TRUE,LOGON_OPTION_HIGHSECURITY))
913 void DoUnMapShare(BOOL drivemap) //disconnect drivemap
915 TCHAR szMachine[ MAX_PATH],szPath[MAX_PATH];
918 LPNETRESOURCE lpnrLocal,lpnr=NULL;
920 DWORD cbBuffer=16384;
922 GetComputerName(szMachine,&rc);
924 // Initialize the data structure
925 if ((res=WNetOpenEnum(RESOURCE_CONNECTED,RESOURCETYPE_DISK,RESOURCEUSAGE_CONNECTABLE,lpnr,&hEnum))!=NO_ERROR)
927 sprintf(szPath,"\\\\%s-afs\\",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 //WNetCancelConnection(lpnrLocal[i].lpLocalName,TRUE);
944 DisMountDOSDriveFull(lpnrLocal[i].lpRemoteName);
945 //WNetCancelConnection(lpnrLocal[i].lpRemoteName,TRUE);
946 DEBUG_EVENT1("AFS DriveUnMap","UnMap-Remote=%x",res);
950 } while (res!=ERROR_NO_MORE_ITEMS);
951 GlobalFree((HGLOBAL)lpnrLocal);
952 WNetCloseEnum(hEnum);
955 BOOL DoMapShareChange()
958 TCHAR szMachine[ MAX_PATH],szPath[MAX_PATH];
961 LPNETRESOURCE lpnrLocal,lpnr=NULL;
963 DWORD cbBuffer=16384;
965 GetComputerName(szMachine,&rc);
966 CHAR szUser[MAXRANDOMNAMELEN];
967 // Initialize the data structure
968 if (!IsServiceActive())
970 memset (&List, 0x00, sizeof(DRIVEMAPLIST));
971 for (size_t ii = 0; ii < 26; ++ii)
972 List.aDriveMap[ii].chDrive = chDRIVE_A + ii;
973 QueryDriveMapList_ReadSubmounts (&List);
974 if ((res=WNetOpenEnum(RESOURCE_CONNECTED,RESOURCETYPE_DISK,RESOURCEUSAGE_CONNECTABLE,lpnr,&hEnum))!=NO_ERROR)
976 lpnrLocal=(LPNETRESOURCE) GlobalAlloc(GPTR,cbBuffer);
977 sprintf(szPath,"\\\\%s-afs\\",szMachine);
980 memset(lpnrLocal,0,cbBuffer);
981 if ((res = WNetEnumResource(hEnum,&cEntries,lpnrLocal,&cbBuffer))==NO_ERROR)
983 for (DWORD i=0;i<cEntries;i++)
985 if (strstr(_strlwr(lpnrLocal[i].lpRemoteName),szPath)==NULL)
986 continue; //only look at real afs mappings
987 CHAR * pSubmount=strrchr(lpnrLocal[i].lpRemoteName,'\\')+1;
988 if (strcmpi(pSubmount,"all")==0)
989 continue; // do not remove 'all'
990 for (DWORD j=0;j<List.cSubmounts;j++)
993 (List.aSubmounts[j].szSubmount[0]) &&
994 (strcmpi(List.aSubmounts[j].szSubmount,pSubmount)==0)
997 List.aSubmounts[j].fInUse=TRUE;
1001 // wasn't on list so lets remove
1002 DisMountDOSDrive(pSubmount);
1006 } while (res!=ERROR_NO_MORE_ITEMS);
1007 GlobalFree((HGLOBAL)lpnrLocal);
1008 WNetCloseEnum(hEnum);
1009 sprintf(szPath,"\\\\%s-afs\\all",szMachine);
1010 cbBuffer=MAXRANDOMNAMELEN-1;
1011 // Lets connect all submounts that weren't connectd
1012 CHAR * pUser=szUser;
1013 if (WNetGetUser(szPath,(LPSTR)szUser,&cbBuffer)!=NO_ERROR)
1014 GenRandomName(szUser,MAXRANDOMNAMELEN-1);
1016 if ((pUser=strchr(szUser,'\\'))==NULL)
1020 for (DWORD j=0;j<List.cSubmounts;j++)
1022 if (List.aSubmounts[j].fInUse)
1024 sprintf(szPath,"\\\\%s-afs\\%s",szMachine,List.aSubmounts[j].szSubmount);
1026 memset (&nr, 0x00, sizeof(NETRESOURCE));
1027 nr.dwType=RESOURCETYPE_DISK;
1029 nr.lpRemoteName=szPath;
1030 //DWORD res=WNetAddConnection2(&nr,NULL,pUser,0);
1031 DWORD res=MountDOSDrive(0,List.aSubmounts[j].szSubmount,FALSE,pUser);
1039 TCHAR szMachine[ MAX_PATH ];
1040 TCHAR szPath[ MAX_PATH ];
1042 BOOL bMappedAll=FALSE;
1043 GetComputerName(szMachine,&rc);
1044 // Initialize the data structure
1045 DEBUG_EVENT0("AFS DoMapShare");
1046 QueryDriveMapList (&List);
1048 // All connections have been removed
1049 // Lets restore them after making the connection from the random name
1051 GenRandomName(pUserName,MAXRANDOMNAMELEN-1);
1052 for (DWORD i=0;i<List.cSubmounts;i++)
1054 if (List.aSubmounts[i].szSubmount[0])
1056 sprintf(szPath,"\\\\%s-afs\\%s",szMachine,List.aSubmounts[i].szSubmount);
1058 memset (&nr, 0x00, sizeof(NETRESOURCE));
1059 nr.dwType=RESOURCETYPE_DISK;
1061 nr.lpRemoteName=szPath;
1062 //DWORD res=WNetAddConnection2(&nr,NULL,pUserName,0);
1063 DWORD res=MountDOSDrive(0,List.aSubmounts[i].szSubmount,FALSE,pUserName);
1064 DEBUG_EVENT2("AFS DriveMap","Remote[%s]=%x",szPath,res);
1065 if (strcmpi("all",List.aSubmounts[i].szSubmount)==0)
1069 if (!bMappedAll) //make sure all is mapped also
1071 sprintf(szPath,"\\\\%s-afs\\all",szMachine);
1073 memset (&nr, 0x00, sizeof(NETRESOURCE));
1074 nr.dwType=RESOURCETYPE_DISK;
1076 nr.lpRemoteName=szPath;
1077 DWORD res=MountDOSDrive(0,"all",FALSE,pUserName);
1078 DEBUG_EVENT2("AFS DriveMap","Remote[%s]=%x",szPath,res);
1079 if (res==ERROR_SESSION_CREDENTIAL_CONFLICT)
1081 DisMountDOSDrive("all");
1082 MountDOSDrive(0,"all",FALSE,pUserName);
1085 for (TCHAR chDrive = chDRIVE_A; chDrive <= chDRIVE_Z; ++chDrive)
1087 if (List.aDriveMap[chDrive-chDRIVE_A].fActive)
1089 DWORD res=MountDOSDrive(chDrive
1090 ,List.aDriveMap[chDrive-chDRIVE_A].szSubmount
1091 ,List.aDriveMap[chDrive-chDRIVE_A].fPersistent);
1097 BOOL GlobalMountDrive()
1099 char szDriveToMapTo[5];
1101 char szKeyName[256];
1105 DWORD dwSubMountSize;
1106 char unsigned szSubMount[256];
1107 char cm_HostName[200];
1108 DWORD dwType=sizeof(cm_HostName);
1109 if (!IsServiceActive())
1111 if (!GetComputerName(cm_HostName, &dwType))
1113 sprintf(szKeyName, "%s\\GlobalAutoMapper", sAFSConfigKeyName);
1115 dwResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE, szKeyName, 0, KEY_QUERY_VALUE,
1117 if (dwResult != ERROR_SUCCESS)
1121 dwDriveSize = sizeof(szDriveToMapTo);
1122 dwSubMountSize = sizeof(szSubMount);
1123 dwResult = RegEnumValue(hKey, dwIndex++, szDriveToMapTo, &dwDriveSize,
1124 0, &dwType, szSubMount, &dwSubMountSize);
1125 if (dwResult != ERROR_MORE_DATA) {
1126 if (dwResult != ERROR_SUCCESS) {
1127 if (dwResult != ERROR_NO_MORE_ITEMS)
1129 DEBUG_EVENT1("AFS DriveMap","Failed to read \GlobalAutoMapper values: %d",dwResult);
1134 dwResult=MountDOSDrive(*szDriveToMapTo,(const char *)szSubMount,FALSE);
1140 DWORD MountDOSDrive(char chDrive,const char *szSubmount,BOOL bPersistent,const char * pUsername)
1142 TCHAR szPath[MAX_PATH];
1143 TCHAR szClient[MAX_PATH];
1144 TCHAR szDrive[3] = TEXT("?:");
1145 sprintf(szDrive,"%c:",chDrive);
1146 GetClientNetbiosName (szClient);
1147 sprintf(szPath,"\\\\%s\\%s",szClient,szSubmount);
1149 memset (&nr, 0x00, sizeof(NETRESOURCE));
1150 nr.dwType=RESOURCETYPE_DISK;
1151 nr.lpLocalName=szDrive;
1152 nr.lpRemoteName=szPath;
1153 nr.dwDisplayType = RESOURCEDISPLAYTYPE_GENERIC;
1154 nr.dwDisplayType = RESOURCEDISPLAYTYPE_SHARE;
1155 DWORD res=WNetAddConnection2(&nr,NULL,pUsername,(bPersistent)?CONNECT_UPDATE_PROFILE:0);
1156 DEBUG_EVENT3("AFS DriveMap","Mount %s Remote[%s]=%x",(bPersistent)?"Persistant" : "NonPresistant",szPath,res);
1160 DWORD DisMountDOSDriveFull(const char *szPath,BOOL bForce)
1162 DWORD res=WNetCancelConnection(szPath,bForce);
1163 DEBUG_EVENT2("AFS DriveMap","Dismount Remote[%s]=%x",szPath,res);
1164 return (res==ERROR_NOT_CONNECTED)?NO_ERROR:res;
1167 DWORD DisMountDOSDrive(const char *pSubmount,BOOL bForce)
1169 TCHAR szPath[MAX_PATH];
1170 TCHAR szClient[MAX_PATH];
1171 GetClientNetbiosName (szClient);
1172 sprintf(szPath,"\\\\%s\\%s",szClient,pSubmount);
1173 return DisMountDOSDriveFull(szPath,bForce);
1177 DWORD DisMountDOSDrive(const char chDrive,BOOL bForce)
1179 TCHAR szPath[MAX_PATH];
1180 sprintf(szPath,"%c:",chDrive);
1181 return DisMountDOSDriveFull(szPath,bForce);