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>
23 #include <winnt/osi_malloc.h>
26 * REGISTRY ___________________________________________________________________
30 #undef AFSConfigKeyName
31 const TCHAR sAFSConfigKeyName[] = TEXT("SYSTEM\\CurrentControlSet\\Services\\TransarcAFSDaemon\\Parameters");
35 * PROFILE SECTIONS ___________________________________________________________
39 #define cREALLOC_SUBMOUNTS 4
41 static TCHAR cszINIFILE[] = TEXT("afsdsbmt.ini");
42 static TCHAR cszSECTION_SUBMOUNTS[] = TEXT("AFS Submounts");
43 static TCHAR cszSECTION_MAPPINGS[] = TEXT("AFS Mappings");
45 static TCHAR cszAUTOSUBMOUNT[] = TEXT("Auto");
46 static TCHAR cszLANMANDEVICE[] = TEXT("\\Device\\LanmanRedirector\\");
50 * STRINGS ____________________________________________________________________
54 static LPTSTR AllocateStringMemory (size_t cch)
56 LPTSTR psz = (LPTSTR)Allocate (sizeof(TCHAR) * (cch+1));
57 memset (psz, 0x00, sizeof(TCHAR) * (cch+1));
61 static void FreeStringMemory (LPTSTR pszString)
66 static int lstrncmpi (LPCTSTR pszA, LPCTSTR pszB, size_t cch)
70 return (!pszB) - (!pszA); // A,!B:1, !A,B:-1, !A,!B:0
73 for ( ; cch > 0; cch--, pszA = CharNext(pszA), pszB = CharNext(pszB))
75 TCHAR chA = toupper( *pszA );
76 TCHAR chB = toupper( *pszB );
79 return (!chB) - (!chA); // A,!B:1, !A,B:-1, !A,!B:0
82 return (int)(chA) - (int)(chB); // -1:A<B, 0:A==B, 1:A>B
85 return 0; // no differences before told to stop comparing, so A==B
90 * REALLOC ____________________________________________________________________
95 #define REALLOC(_a,_c,_r,_i) DriveMapReallocFunction ((LPVOID*)&_a,sizeof(*_a),&_c,_r,_i)
96 BOOL DriveMapReallocFunction (LPVOID *ppTarget, size_t cbElement, size_t *pcTarget, size_t cReq, size_t cInc)
101 if (cReq <= *pcTarget)
104 if ((cNew = cInc * ((cReq + cInc-1) / cInc)) <= 0)
107 if ((pNew = Allocate (cbElement * cNew)) == NULL)
109 memset (pNew, 0x00, cbElement * cNew);
113 memcpy (pNew, *ppTarget, cbElement * (*pcTarget));
125 * WINDOWS NT STUFF ___________________________________________________________
129 static BOOL IsWindowsNT (void)
131 static BOOL fChecked = FALSE;
132 static BOOL fIsWinNT = FALSE;
138 OSVERSIONINFO Version;
139 memset (&Version, 0x00, sizeof(Version));
140 Version.dwOSVersionInfoSize = sizeof(Version);
142 if (GetVersionEx (&Version))
144 if (Version.dwPlatformId == VER_PLATFORM_WIN32_NT)
153 BOOL IsWindows2000 (void)
155 static BOOL fChecked = FALSE;
156 static BOOL fIsWin2K = FALSE;
162 OSVERSIONINFO Version;
163 memset (&Version, 0x00, sizeof(Version));
164 Version.dwOSVersionInfoSize = sizeof(Version);
166 if (GetVersionEx (&Version))
168 if (Version.dwPlatformId == VER_PLATFORM_WIN32_NT &&
169 Version.dwMajorVersion >= 5)
178 * GENERAL ____________________________________________________________________
182 void GetClientNetbiosName (LPTSTR pszName)
184 *pszName = TEXT('\0');
189 if (RegOpenKey (HKEY_LOCAL_MACHINE, TEXT("System\\CurrentControlSet\\Control\\ComputerName\\ComputerName"), &hk) == 0)
191 DWORD dwSize = MAX_PATH;
192 DWORD dwType = REG_SZ;
193 RegQueryValueEx (hk, TEXT("ComputerName"), NULL, &dwType, (PBYTE)pszName, &dwSize);
196 else // (!IsWindowsNT())
199 if (RegOpenKey (HKEY_LOCAL_MACHINE, TEXT("System\\CurrentControlSet\\Services\\TransarcAFSDaemon\\Parameters"), &hk) == 0)
201 DWORD dwSize = MAX_PATH;
202 DWORD dwType = REG_SZ;
203 RegQueryValueEx (hk, TEXT("Gateway"), NULL, &dwType, (PBYTE)pszName, &dwSize);
207 // Shorten the server name from its FQDN
209 for (LPTSTR pch = pszName; *pch; ++pch)
211 if (*pch == TEXT('.'))
213 *(LPTSTR)pch = TEXT('\0');
218 // Form NetBIOS name from client's (possibly truncated) simple host name.
219 if (*pszName != TEXT('\0')) {
220 pszName[11] = TEXT('\0');
221 lstrcat(pszName, TEXT("-AFS"));
226 BOOL SubmountToPath (PDRIVEMAPLIST pList, LPTSTR pszPath, LPTSTR pszSubmount, BOOL fMarkInUse)
228 // We can't do this translation unless we're under Windows NT.
233 // \\computer-afs\all always maps to "/afs"
235 if (!lstrcmpi (pszSubmount, TEXT("all")))
237 lstrcpy (pszPath, TEXT("/afs"));
241 // Otherwise, look up our list of submounts.
243 for (size_t ii = 0; ii < pList->cSubmounts; ++ii)
245 if (!lstrcmpi (pList->aSubmounts[ii].szSubmount, pszSubmount))
248 pList->aSubmounts[ii].fInUse = TRUE;
249 AdjustAfsPath (pszPath, pList->aSubmounts[ii].szMapping, TRUE, TRUE);
258 BOOL IsValidSubmountName (LPTSTR pszSubmount)
262 if (lstrlen (pszSubmount) > 12)
265 for ( ; *pszSubmount; ++pszSubmount)
267 if (!isprint(*pszSubmount))
269 if (*pszSubmount == TEXT(' '))
271 if (*pszSubmount == TEXT('\t'))
280 * PIOCTL SUPPORT _____________________________________________________________
286 #include "../afsd/fs_utils.h"
288 #define __CM_CONFIG_INTERFACES_ONLY__
289 #include "../afsd/cm_config.h"
291 #define __CM_IOCTL_INTERFACES_ONLY__
292 #include "../afsd/cm_ioctl.h"
296 #define PIOCTL_MAXSIZE 2048
299 BOOL fCanIssuePIOCTL (void)
303 TCHAR szGateway[ 256 ] = TEXT("");
304 GetClientNetbiosName (szGateway);
305 return (szGateway[0]) ? TRUE : FALSE;
308 SERVICE_STATUS Status;
309 memset (&Status, 0x00, sizeof(Status));
310 Status.dwCurrentState = SERVICE_STOPPED;
313 if ((hManager = OpenSCManager (NULL, NULL, GENERIC_READ)) != NULL)
316 if ((hService = OpenService (hManager, TEXT("TransarcAFSDaemon"), GENERIC_READ)) != NULL)
318 QueryServiceStatus (hService, &Status);
319 CloseServiceHandle (hService);
322 CloseServiceHandle (hManager);
325 return (Status.dwCurrentState == SERVICE_RUNNING) ? TRUE : FALSE;
330 * QUERYDRIVEMAPLIST __________________________________________________________
334 void QueryDriveMapList_ReadSubmounts (PDRIVEMAPLIST pList)
338 size_t cchLHS = 1024;
339 LPTSTR mszLHS = AllocateStringMemory (cchLHS);
341 for (int iRetry = 0; iRetry < 5; ++iRetry)
343 DWORD rc = GetPrivateProfileString (cszSECTION_SUBMOUNTS, NULL, TEXT(""), mszLHS, cchLHS, cszINIFILE);
344 if ((rc != cchLHS-1) && (rc != cchLHS-2))
347 FreeStringMemory (mszLHS);
349 mszLHS = AllocateStringMemory (cchLHS);
352 for (LPTSTR psz = mszLHS; psz && *psz; psz += 1+lstrlen(psz))
355 memset (&Submount, 0x00, sizeof(SUBMOUNT));
356 lstrcpy (Submount.szSubmount, psz);
358 TCHAR szMapping[ MAX_PATH ] = TEXT("");
359 GetPrivateProfileString (cszSECTION_SUBMOUNTS, Submount.szSubmount, TEXT(""), szMapping, MAX_PATH, cszINIFILE);
360 if (szMapping[0] != TEXT('\0'))
362 AdjustAfsPath (Submount.szMapping, szMapping, FALSE, TRUE);
364 for (size_t ii = 0; ii < pList->cSubmounts; ++ii)
366 if (!pList->aSubmounts[ii].szSubmount[0])
369 if (REALLOC (pList->aSubmounts, pList->cSubmounts, 1+ii, cREALLOC_SUBMOUNTS))
371 memcpy (&pList->aSubmounts[ii], &Submount, sizeof(SUBMOUNT));
376 FreeStringMemory (mszLHS);
381 void QueryDriveMapList_ReadMappings (PDRIVEMAPLIST pList)
383 size_t cchLHS = 1024;
384 LPTSTR mszLHS = AllocateStringMemory (cchLHS);
386 for (int iRetry = 0; iRetry < 5; ++iRetry)
388 DWORD rc = GetPrivateProfileString (cszSECTION_MAPPINGS, NULL, TEXT(""), mszLHS, cchLHS, cszINIFILE);
389 if ((rc != cchLHS-1) && (rc != cchLHS-2))
392 FreeStringMemory (mszLHS);
394 mszLHS = AllocateStringMemory (cchLHS);
397 for (LPTSTR psz = mszLHS; psz && *psz; psz += 1+lstrlen(psz))
400 memset (&DriveMap, 0x00, sizeof(DRIVEMAP));
401 DriveMap.chDrive = toupper(*psz);
402 DriveMap.fPersistent = TRUE;
403 if ((DriveMap.chDrive < chDRIVE_A) || (DriveMap.chDrive > chDRIVE_Z))
406 TCHAR szMapping[ MAX_PATH ] = TEXT("");
407 GetPrivateProfileString (cszSECTION_MAPPINGS, psz, TEXT(""), szMapping, MAX_PATH, cszINIFILE);
408 if (szMapping[0] != TEXT('\0'))
410 AdjustAfsPath (DriveMap.szMapping, szMapping, TRUE, TRUE);
411 if (DriveMap.szMapping[ lstrlen(DriveMap.szMapping)-1 ] == TEXT('*'))
413 DriveMap.fPersistent = FALSE;
414 DriveMap.szMapping[ lstrlen(DriveMap.szMapping)-1 ] = TEXT('\0');
416 size_t iDrive = DriveMap.chDrive - chDRIVE_A;
417 memcpy (&pList->aDriveMap[ iDrive ], &DriveMap, sizeof(DRIVEMAP));
421 FreeStringMemory (mszLHS);
425 void QueryDriveMapList_WriteMappings (PDRIVEMAPLIST pList)
427 WriteDriveMappings (pList);
431 void WriteDriveMappings (PDRIVEMAPLIST pList)
433 WritePrivateProfileString (cszSECTION_MAPPINGS, NULL, NULL, cszINIFILE);
435 for (size_t iDrive = 0; iDrive < 26; ++iDrive)
437 if (pList->aDriveMap[iDrive].szMapping[0] != TEXT('\0'))
439 TCHAR szLHS[] = TEXT("*");
440 szLHS[0] = pList->aDriveMap[iDrive].chDrive;
442 TCHAR szRHS[MAX_PATH];
443 AdjustAfsPath (szRHS, pList->aDriveMap[iDrive].szMapping, TRUE, TRUE);
444 if (!pList->aDriveMap[iDrive].fPersistent)
445 lstrcat (szRHS, TEXT("*"));
447 WritePrivateProfileString (cszSECTION_MAPPINGS, szLHS, szRHS, cszINIFILE);
452 BOOL DriveIsGlobalAfsDrive(TCHAR chDrive)
454 TCHAR szKeyName[128];
455 TCHAR szValueName[128];
459 _stprintf(szKeyName, TEXT("%s\\GlobalAutoMapper"), sAFSConfigKeyName);
461 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, szKeyName, 0, KEY_QUERY_VALUE, &hKey) != ERROR_SUCCESS)
464 _stprintf(szValueName, TEXT("%c:"), chDrive);
466 DWORD dwSize = sizeof(szValue);
467 BOOL bIsGlobal = (RegQueryValueEx (hKey, szValueName, NULL, NULL, (PBYTE)szValue, &dwSize) == ERROR_SUCCESS);
475 void QueryDriveMapList_FindNetworkDrives (PDRIVEMAPLIST pList, BOOL *pfFoundNew)
477 for (TCHAR chDrive = chDRIVE_A; chDrive <= chDRIVE_Z; ++chDrive)
479 TCHAR szSubmount[ MAX_PATH ];
480 if (!GetDriveSubmount (chDrive, szSubmount))
483 // We've got a mapping! Drive {chDrive} is mapped to submount
484 // {szSubmount}. See if that submount makes sense.
488 size_t iDrive = chDrive - chDRIVE_A;
489 if (pList->aDriveMap[ iDrive ].szMapping[0] != TEXT('\0'))
491 pList->aDriveMap[ iDrive ].fActive = TRUE;
492 lstrcpy (pList->aDriveMap[ iDrive ].szSubmount, szSubmount);
496 else // (IsWindowsNT())
498 TCHAR szAfsPath[ MAX_PATH ];
499 if (!SubmountToPath (pList, szAfsPath, szSubmount, TRUE))
502 // Okay, we know that drive {chDrive} is mapped to afs path {szAfsPath}.
503 // If this drive is a global afs drive, then reject it. Otherwise, look
504 // at pList->aDriveMap, to see if this drive mapping is already in our
505 // list. If not, add it and set pfFoundNew.
507 if (DriveIsGlobalAfsDrive(chDrive))
510 size_t iDrive = chDrive - chDRIVE_A;
511 if (lstrcmpi (pList->aDriveMap[ iDrive ].szMapping, szAfsPath))
514 pList->aDriveMap[ iDrive ].fPersistent = TRUE;
516 pList->aDriveMap[ iDrive ].fActive = TRUE;
517 pList->aDriveMap[ iDrive ].chDrive = chDrive;
518 lstrcpy (pList->aDriveMap[ iDrive ].szSubmount, szSubmount);
519 AdjustAfsPath (pList->aDriveMap[ iDrive ].szMapping, szAfsPath, TRUE, TRUE);
525 void QueryDriveMapList (PDRIVEMAPLIST pList)
527 // Initialize the data structure
529 memset (pList, 0x00, sizeof(DRIVEMAPLIST));
530 for (size_t ii = 0; ii < 26; ++ii)
531 pList->aDriveMap[ii].chDrive = chDRIVE_A + ii;
533 // Read the current lists of submounts and drive letter mappings
535 QueryDriveMapList_ReadSubmounts (pList);
536 QueryDriveMapList_ReadMappings (pList);
538 // Look through the current list of network drives, and see if
539 // any are currently mapped to AFS. If we find any which are mapped
540 // into AFS unexpectedly, we'll have to rewrite the mappings list.
542 BOOL fFoundNew = FALSE;
543 QueryDriveMapList_FindNetworkDrives (pList, &fFoundNew);
547 QueryDriveMapList_WriteMappings (pList);
552 void FreeDriveMapList (PDRIVEMAPLIST pList)
554 if (pList->aSubmounts)
555 Free (pList->aSubmounts);
556 memset (pList, 0x00, sizeof(DRIVEMAPLIST));
560 BOOL PathToSubmount (LPTSTR pszSubmount, LPTSTR pszMapping, LPTSTR pszSubmountReq, ULONG *pStatus)
562 if (pszSubmountReq && !IsValidSubmountName (pszSubmountReq))
563 pszSubmountReq = NULL;
565 TCHAR szAfsPath[ MAX_PATH ];
566 AdjustAfsPath (szAfsPath, pszMapping, TRUE, TRUE);
568 // Try to ask AFSD for a new submount name.
570 if (!fCanIssuePIOCTL())
573 BYTE InData[ PIOCTL_MAXSIZE ];
574 memset (InData, 0x00, sizeof(InData));
576 LPTSTR pszInData = (LPTSTR)InData;
577 lstrcpy (pszInData, pszMapping);
578 pszInData += 1+lstrlen(pszInData);
580 lstrcpy (pszInData, pszSubmountReq);
582 BYTE OutData[ PIOCTL_MAXSIZE ];
583 memset (OutData, 0x00, sizeof(OutData));
585 struct ViceIoctl IOInfo;
586 IOInfo.in = (char *)InData;
587 IOInfo.in_size = PIOCTL_MAXSIZE;
588 IOInfo.out = (char *)OutData;
589 IOInfo.out_size = PIOCTL_MAXSIZE;
592 if ((status = pioctl (0, VIOC_MAKESUBMOUNT, &IOInfo, 1)) != 0)
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, TEXT("/afs"), lstrlen(TEXT("/afs")))) &&
605 (lstrncmpi (pszMapping, TEXT("\\afs"), lstrlen(TEXT("\\afs")))) )
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 NETRESOURCE Resource;
636 memset (&Resource, 0x00, sizeof(NETRESOURCE));
637 Resource.dwScope = RESOURCE_GLOBALNET;
638 Resource.dwType = RESOURCETYPE_DISK;
639 Resource.dwDisplayType = RESOURCEDISPLAYTYPE_SHARE;
640 Resource.dwUsage = RESOURCEUSAGE_CONNECTABLE;
641 Resource.lpLocalName = szLocal;
642 Resource.lpRemoteName = szRemote;
644 // DWORD rc = WNetAddConnection2 (&Resource, NULL, NULL, ((fPersistent) ? CONNECT_UPDATE_PROFILE : 0));
645 DWORD rc=MountDOSDrive(chDrive,szSubmount,fPersistent);
655 BOOL InactivateDriveMap (TCHAR chDrive, DWORD *pdwStatus)
657 DWORD rc = DisMountDOSDrive(chDrive, FALSE);
667 void AddSubMount (LPTSTR pszSubmount, LPTSTR pszMapping)
669 TCHAR szRHS[ MAX_PATH ];
670 AdjustAfsPath (szRHS, pszMapping, FALSE, TRUE);
672 lstrcpy (szRHS, TEXT("/"));
673 WritePrivateProfileString (cszSECTION_SUBMOUNTS, pszSubmount, szRHS, cszINIFILE);
677 void RemoveSubMount (LPTSTR pszSubmount)
679 WritePrivateProfileString (cszSECTION_SUBMOUNTS, pszSubmount, NULL, cszINIFILE);
683 void AdjustAfsPath (LPTSTR pszTarget, LPCTSTR pszSource, BOOL fWantAFS, BOOL fWantForwardSlashes)
686 lstrcpy (pszTarget, (fWantAFS) ? TEXT("/afs") : TEXT(""));
687 else if ((*pszSource != TEXT('/')) && (*pszSource != TEXT('\\')))
688 wsprintf (pszTarget, TEXT("/afs/%s"), pszSource);
689 // We don't want to strip afs off the start if it is part of something for example afscell.company.com
690 else if (fWantAFS && (lstrncmpi (&pszSource[1], TEXT("afs"), 3)) || !((pszSource[4] == TEXT('/')) ||
691 (pszSource[4] == TEXT('\\')) ||
692 (lstrlen(pszSource) == 4)))
693 wsprintf (pszTarget, TEXT("/afs%s"), pszSource);
694 else if (!fWantAFS && (!lstrncmpi (&pszSource[1], TEXT("afs"), 3) && ((pszSource[4] == TEXT('/')) ||
695 (pszSource[4] == TEXT('\\')) ||
696 (lstrlen(pszSource) == 4))))
697 lstrcpy (pszTarget, &pszSource[4]);
699 lstrcpy (pszTarget, pszSource);
701 for (LPTSTR pch = pszTarget; *pch; ++pch)
703 if (fWantForwardSlashes)
705 *pch = (*pch == TEXT('\\')) ? TEXT('/') : (*pch);
707 else // (!fWantForwardSlashes)
709 *pch = (*pch == TEXT('/')) ? TEXT('\\') : (*pch);
713 if (lstrlen(pszTarget) &&
714 ((pszTarget[lstrlen(pszTarget)-1] == TEXT('/')) ||
715 (pszTarget[lstrlen(pszTarget)-1] == TEXT('\\'))))
717 pszTarget[lstrlen(pszTarget)-1] = TEXT('\0');
722 BOOL GetDriveSubmount (TCHAR chDrive, LPTSTR pszSubmountNow)
724 TCHAR szDrive[] = TEXT("*:");
725 szDrive[0] = chDrive;
727 TCHAR szMapping[ MAX_PATH ] = TEXT("");
728 LPTSTR pszSubmount = szMapping;
732 QueryDosDevice (szDrive, szMapping, MAX_PATH);
734 // Now if this is an AFS network drive mapping, {szMapping} will be:
736 // \Device\LanmanRedirector\Q:\machine-afs\submount
738 // on Windows NT. On Windows 2000, it will be:
740 // \Device\LanmanRedirector\;Q:0\machine-afs\submount
742 // (This is presumably to support multiple drive mappings with
745 if (lstrncmpi (szMapping, cszLANMANDEVICE, lstrlen(cszLANMANDEVICE)))
747 pszSubmount = &szMapping[ lstrlen(cszLANMANDEVICE) ];
751 if (*(pszSubmount) != TEXT(';'))
756 if (toupper(*(++pszSubmount)) != chDrive)
759 if (*(++pszSubmount) != TEXT(':'))
763 if (*(++pszSubmount) != TEXT('0'))
767 while (*(++pszSubmount) != TEXT('\\'))
772 for (++pszSubmount; *pszSubmount && (*pszSubmount != TEXT('\\')); ++pszSubmount)
773 if (!lstrncmpi (pszSubmount, TEXT("-afs\\"), lstrlen(TEXT("-afs\\"))))
775 if ((!*pszSubmount) || (*pszSubmount == TEXT('\\')))
777 pszSubmount += lstrlen("-afs\\");
779 else // (!IsWindowsNT())
781 DWORD dwSize = MAX_PATH;
782 if (WNetGetConnection (szDrive, szMapping, &dwSize) != NO_ERROR)
784 if (*(pszSubmount++) != TEXT('\\'))
786 if (*(pszSubmount++) != TEXT('\\'))
788 for ( ; *pszSubmount && (*pszSubmount != TEXT('\\')); ++pszSubmount)
789 if (!lstrncmpi (pszSubmount, TEXT("-afs\\"), lstrlen(TEXT("-afs\\"))))
791 if ((!*pszSubmount) || (*pszSubmount == TEXT('\\')))
793 pszSubmount += lstrlen("-afs\\");
796 if (!pszSubmount || !*pszSubmount)
799 lstrcpy (pszSubmountNow, pszSubmount);
803 /* Generate Random User name random acording to time*/
805 TCHAR pUserName[MAXRANDOMNAMELEN];
806 BOOL fUserName=FALSE;
807 #define AFSLogonOptionName TEXT("System\\CurrentControlSet\\Services\\TransarcAFSDaemon\\NetworkProvider")
809 void SetBitLogonOption(BOOL set,DWORD value)
812 RWLogonOption(FALSE,((set)?value | RWLogonOption(TRUE,0):RWLogonOption(TRUE,0) & ~value) );
815 DWORD RWLogonOption(BOOL read,DWORD value)
817 // if read is true then if value==0 return registry value
818 // if read and value!=0 then use value to test registry, return TRUE if value bits match value read
821 DWORD LSPtype, LSPsize;
826 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, AFSLogonOptionName,0, KEY_QUERY_VALUE, &hk)==ERROR_SUCCESS)
828 LSPsize=sizeof(rval);
829 RegQueryValueEx(hk, "LogonOptions", NULL,
830 &LSPtype, (LPBYTE)&rval, &LSPsize);
833 return (value==0)?rval:((rval & value)==value);
836 if (RegCreateKeyEx (HKEY_LOCAL_MACHINE, AFSLogonOptionName, 0, NULL, 0, KEY_SET_VALUE, NULL, &hk, &dwDisp) == ERROR_SUCCESS)
838 RegSetValueEx(hk,TEXT("LogonOptions"),NULL,REG_DWORD,(LPBYTE)&value,sizeof(value));
845 void MapShareName(char *pszCmdLineA)
850 while (*pszCmdLineA && (*pszCmdLineA != ' '))
856 void GenRandomName(TCHAR *pname,int len)
859 { //user name was passed through command line, use once
863 srand( (unsigned)time( NULL ) );
864 for (int i=0;i<len;i++)
865 pname[i]='a'+(rand() % 26);
871 Make a connection using users name
872 if fUserName then force a connection
875 BOOL TestAndDoMapShare(DWORD dwState)
877 if ((dwState!=SERVICE_RUNNING) || (dwOldState!=SERVICE_START_PENDING))
882 dwOldState=SERVICE_RUNNING;
883 if (RWLogonOption(TRUE,LOGON_OPTION_HIGHSECURITY))
884 return (DoMapShare() && GlobalMountDrive());
885 return GlobalMountDrive();
888 BOOL IsServiceActive()
891 SERVICE_STATUS Status;
892 if ((hManager = OpenSCManager (NULL, NULL, GENERIC_READ)) != NULL)
895 if ((hService = OpenService (hManager, TEXT("TransarcAFSDaemon"), GENERIC_READ)) != NULL)
897 QueryServiceStatus (hService, &Status);
898 CloseServiceHandle (hService);
901 CloseServiceHandle (hManager);
904 return (Status.dwCurrentState == SERVICE_RUNNING) ? TRUE : FALSE;
907 void TestAndDoUnMapShare()
909 if (!RWLogonOption(TRUE,LOGON_OPTION_HIGHSECURITY))
914 void DoUnMapShare(BOOL drivemap) //disconnect drivemap
916 TCHAR szMachine[ MAX_PATH],szPath[MAX_PATH];
919 LPNETRESOURCE lpnrLocal,lpnr=NULL;
921 DWORD cbBuffer=16384;
923 GetComputerName(szMachine,&rc);
925 // Initialize the data structure
926 if ((res=WNetOpenEnum(RESOURCE_CONNECTED,RESOURCETYPE_DISK,RESOURCEUSAGE_CONNECTABLE,lpnr,&hEnum))!=NO_ERROR)
928 sprintf(szPath,"\\\\%s-afs\\",szMachine);
930 lpnrLocal=(LPNETRESOURCE) GlobalAlloc(GPTR,cbBuffer);
932 memset(lpnrLocal,0,cbBuffer);
933 if ((res = WNetEnumResource(hEnum,&cEntries,lpnrLocal,&cbBuffer))==NO_ERROR)
935 for (DWORD i=0;i<cEntries;i++)
937 if (strstr(_strlwr(lpnrLocal[i].lpRemoteName),szPath))
939 if ((lpnrLocal[i].lpLocalName) && (strlen(lpnrLocal[i].lpLocalName)>0))
942 DisMountDOSDrive(*lpnrLocal[i].lpLocalName);
943 //WNetCancelConnection(lpnrLocal[i].lpLocalName,TRUE);
945 DisMountDOSDriveFull(lpnrLocal[i].lpRemoteName);
946 //WNetCancelConnection(lpnrLocal[i].lpRemoteName,TRUE);
947 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;
964 DWORD cbBuffer=16384;
966 GetComputerName(szMachine,&rc);
967 CHAR szUser[MAXRANDOMNAMELEN];
968 // Initialize the data structure
969 if (!IsServiceActive())
971 memset (&List, 0x00, sizeof(DRIVEMAPLIST));
972 for (size_t ii = 0; ii < 26; ++ii)
973 List.aDriveMap[ii].chDrive = chDRIVE_A + ii;
974 QueryDriveMapList_ReadSubmounts (&List);
975 if ((res=WNetOpenEnum(RESOURCE_CONNECTED,RESOURCETYPE_DISK,RESOURCEUSAGE_CONNECTABLE,lpnr,&hEnum))!=NO_ERROR)
977 lpnrLocal=(LPNETRESOURCE) GlobalAlloc(GPTR,cbBuffer);
978 sprintf(szPath,"\\\\%s-afs\\",szMachine);
981 memset(lpnrLocal,0,cbBuffer);
982 if ((res = WNetEnumResource(hEnum,&cEntries,lpnrLocal,&cbBuffer))==NO_ERROR)
984 for (DWORD i=0;i<cEntries;i++)
986 if (strstr(_strlwr(lpnrLocal[i].lpRemoteName),szPath)==NULL)
987 continue; //only look at real afs mappings
988 CHAR * pSubmount=strrchr(lpnrLocal[i].lpRemoteName,'\\')+1;
989 if (strcmpi(pSubmount,"all")==0)
990 continue; // do not remove 'all'
991 for (DWORD j=0;j<List.cSubmounts;j++)
994 (List.aSubmounts[j].szSubmount[0]) &&
995 (strcmpi(List.aSubmounts[j].szSubmount,pSubmount)==0)
998 List.aSubmounts[j].fInUse=TRUE;
1002 // wasn't on list so lets remove
1003 DisMountDOSDrive(pSubmount);
1007 } while (res!=ERROR_NO_MORE_ITEMS);
1008 GlobalFree((HGLOBAL)lpnrLocal);
1009 WNetCloseEnum(hEnum);
1010 sprintf(szPath,"\\\\%s-afs\\all",szMachine);
1011 cbBuffer=MAXRANDOMNAMELEN-1;
1012 // Lets connect all submounts that weren't connectd
1013 CHAR * pUser=szUser;
1014 if (WNetGetUser(szPath,(LPSTR)szUser,&cbBuffer)!=NO_ERROR)
1015 GenRandomName(szUser,MAXRANDOMNAMELEN-1);
1017 if ((pUser=strchr(szUser,'\\'))==NULL)
1021 for (DWORD j=0;j<List.cSubmounts;j++)
1023 if (List.aSubmounts[j].fInUse)
1025 sprintf(szPath,"\\\\%s-afs\\%s",szMachine,List.aSubmounts[j].szSubmount);
1027 memset (&nr, 0x00, sizeof(NETRESOURCE));
1028 nr.dwType=RESOURCETYPE_DISK;
1030 nr.lpRemoteName=szPath;
1031 //DWORD res=WNetAddConnection2(&nr,NULL,pUser,0);
1032 DWORD res=MountDOSDrive(0,List.aSubmounts[j].szSubmount,FALSE,pUser);
1040 TCHAR szMachine[ MAX_PATH ];
1041 TCHAR szPath[ MAX_PATH ];
1043 BOOL bMappedAll=FALSE;
1044 GetComputerName(szMachine,&rc);
1045 // Initialize the data structure
1046 DEBUG_EVENT0("AFS DoMapShare");
1047 QueryDriveMapList (&List);
1049 // All connections have been removed
1050 // Lets restore them after making the connection from the random name
1052 GenRandomName(pUserName,MAXRANDOMNAMELEN-1);
1053 for (DWORD i=0;i<List.cSubmounts;i++)
1055 if (List.aSubmounts[i].szSubmount[0])
1057 sprintf(szPath,"\\\\%s-afs\\%s",szMachine,List.aSubmounts[i].szSubmount);
1059 memset (&nr, 0x00, sizeof(NETRESOURCE));
1060 nr.dwType=RESOURCETYPE_DISK;
1062 nr.lpRemoteName=szPath;
1063 //DWORD res=WNetAddConnection2(&nr,NULL,pUserName,0);
1064 DWORD res=MountDOSDrive(0,List.aSubmounts[i].szSubmount,FALSE,pUserName);
1065 DEBUG_EVENT2("AFS DriveMap","Remote[%s]=%x",szPath,res);
1066 if (strcmpi("all",List.aSubmounts[i].szSubmount)==0)
1070 if (!bMappedAll) //make sure all is mapped also
1072 sprintf(szPath,"\\\\%s-afs\\all",szMachine);
1074 memset (&nr, 0x00, sizeof(NETRESOURCE));
1075 nr.dwType=RESOURCETYPE_DISK;
1077 nr.lpRemoteName=szPath;
1078 DWORD res=MountDOSDrive(0,"all",FALSE,pUserName);
1079 DEBUG_EVENT2("AFS DriveMap","Remote[%s]=%x",szPath,res);
1080 if (res==ERROR_SESSION_CREDENTIAL_CONFLICT)
1082 DisMountDOSDrive("all");
1083 MountDOSDrive(0,"all",FALSE,pUserName);
1086 for (TCHAR chDrive = chDRIVE_A; chDrive <= chDRIVE_Z; ++chDrive)
1088 if (List.aDriveMap[chDrive-chDRIVE_A].fActive)
1090 DWORD res=MountDOSDrive(chDrive
1091 ,List.aDriveMap[chDrive-chDRIVE_A].szSubmount
1092 ,List.aDriveMap[chDrive-chDRIVE_A].fPersistent);
1098 BOOL GlobalMountDrive()
1100 char szDriveToMapTo[5];
1102 char szKeyName[256];
1106 DWORD dwSubMountSize;
1107 char unsigned szSubMount[256];
1108 char cm_HostName[200];
1109 DWORD dwType=sizeof(cm_HostName);
1110 if (!IsServiceActive())
1112 if (!GetComputerName(cm_HostName, &dwType))
1114 sprintf(szKeyName, "%s\\GlobalAutoMapper", sAFSConfigKeyName);
1116 dwResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE, szKeyName, 0, KEY_QUERY_VALUE,
1118 if (dwResult != ERROR_SUCCESS)
1122 dwDriveSize = sizeof(szDriveToMapTo);
1123 dwSubMountSize = sizeof(szSubMount);
1124 dwResult = RegEnumValue(hKey, dwIndex++, szDriveToMapTo, &dwDriveSize,
1125 0, &dwType, szSubMount, &dwSubMountSize);
1126 if (dwResult != ERROR_MORE_DATA) {
1127 if (dwResult != ERROR_SUCCESS) {
1128 if (dwResult != ERROR_NO_MORE_ITEMS)
1130 DEBUG_EVENT1("AFS DriveMap","Failed to read \GlobalAutoMapper values: %d",dwResult);
1135 dwResult=MountDOSDrive(*szDriveToMapTo,(const char *)szSubMount,FALSE);
1141 DWORD MountDOSDrive(char chDrive,const char *szSubmount,BOOL bPersistent,const char * pUsername)
1143 TCHAR szPath[MAX_PATH];
1144 TCHAR szClient[MAX_PATH];
1145 TCHAR szDrive[3] = TEXT("?:");
1146 sprintf(szDrive,"%c:",chDrive);
1147 GetClientNetbiosName (szClient);
1148 sprintf(szPath,"\\\\%s\\%s",szClient,szSubmount);
1150 memset (&nr, 0x00, sizeof(NETRESOURCE));
1151 nr.dwType=RESOURCETYPE_DISK;
1152 nr.lpLocalName=szDrive;
1153 nr.lpRemoteName=szPath;
1154 nr.dwDisplayType = RESOURCEDISPLAYTYPE_GENERIC;
1155 nr.dwDisplayType = RESOURCEDISPLAYTYPE_SHARE;
1156 DWORD res=WNetAddConnection2(&nr,NULL,pUsername,(bPersistent)?CONNECT_UPDATE_PROFILE:0);
1157 DEBUG_EVENT3("AFS DriveMap","Mount %s Remote[%s]=%x",(bPersistent)?"Persistant" : "NonPresistant",szPath,res);
1161 DWORD DisMountDOSDriveFull(const char *szPath,BOOL bForce)
1163 DWORD res=WNetCancelConnection(szPath,bForce);
1164 DEBUG_EVENT2("AFS DriveMap","Dismount Remote[%s]=%x",szPath,res);
1165 return (res==ERROR_NOT_CONNECTED)?NO_ERROR:res;
1168 DWORD DisMountDOSDrive(const char *pSubmount,BOOL bForce)
1170 TCHAR szPath[MAX_PATH];
1171 TCHAR szClient[MAX_PATH];
1172 GetClientNetbiosName (szClient);
1173 sprintf(szPath,"\\\\%s\\%s",szClient,pSubmount);
1174 return DisMountDOSDriveFull(szPath,bForce);
1178 DWORD DisMountDOSDrive(const char chDrive,BOOL bForce)
1180 TCHAR szPath[MAX_PATH];
1181 sprintf(szPath,"%c:",chDrive);
1182 return DisMountDOSDriveFull(szPath,bForce);