2a8e30c01685ba523d6da63abbb44384619bde8b
[openafs.git] / src / WINNT / client_config / drivemap.cpp
1 /*
2  * Copyright 2000, International Business Machines Corporation and others.
3  * All Rights Reserved.
4  * 
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
8  */
9 /* AFSIFS portions copyright (c) 2005
10  * the regents of the university of michigan
11  * all rights reserved
12  * 
13  * permission is granted to use, copy, create derivative works and
14  * redistribute this software and such derivative works for any purpose,
15  * so long as no fee is charged, and so long as the copyright notice
16  * above, this grant of permission, and the disclaimer below appear
17  * in all copies made; and so long as the name of the university of
18  * michigan is not used in any advertising or publicity pertaining
19  * to the use or distribution of this software without specific, written
20  * prior authorization.
21  * 
22  * this software is provided as is, without representation from the
23  * university of michigan as to its fitness for any purpose, and without
24  * warranty by the university of michigan of any kind, either express
25  * or implied, including without limitation the implied warranties of
26  * merchantability and fitness for a particular purpose.  the regents
27  * of the university of michigan shall not be liable for nay damages,
28  * including special, indirect, incidental, or consequential damages,
29  * with respect to ant claim arising out of or in connection with the
30  * use of the software, even if it has been or is hereafter advised
31  * of the possibility of such damages.
32  */
33
34 extern "C" {
35 #include <afs/param.h>
36 #include <afs/stds.h>
37 #include <rx/rxkad.h>
38 #include <afs/fs_utils.h>
39 }
40 #include <windows.h>
41 #include <stdlib.h>
42 #include <stdio.h>
43 #include <WINNT/TaLocale.h>
44 #include <WINNT/afsreg.h>
45 #undef REALLOC
46 #include "drivemap.h"
47 #include <time.h>
48 #include <adssts.h>
49 #ifdef DEBUG
50 #define DEBUG_VERBOSE
51 #endif
52 #include <osilog.h>
53 #include <lanahelper.h>
54 #include <strsafe.h>
55
56 extern void Config_GetLanAdapter (ULONG *pnLanAdapter);
57
58 /*
59  * REGISTRY ___________________________________________________________________
60  *
61  */
62
63
64 /*
65  * PROFILE SECTIONS ___________________________________________________________
66  *
67  */
68
69 #define cREALLOC_SUBMOUNTS   4
70
71 static TCHAR cszSECTION_SUBMOUNTS[] = TEXT(AFSREG_CLT_OPENAFS_SUBKEY "\\Submounts");
72 static TCHAR cszSECTION_MAPPINGS[]  = TEXT(AFSREG_CLT_OPENAFS_SUBKEY "\\Mappings");
73 static TCHAR cszSECTION_ACTIVE[]    = TEXT(AFSREG_CLT_OPENAFS_SUBKEY "\\Active Maps");
74
75 static TCHAR cszAUTOSUBMOUNT[] = TEXT("Auto");
76 static TCHAR cszLANMANDEVICE[] = TEXT("\\Device\\LanmanRedirector\\");
77
78
79 static BOOL 
80 WriteRegistryString(HKEY key, TCHAR * subkey, LPTSTR lhs, LPTSTR rhs)
81 {
82     HKEY hkSub = NULL;
83     RegCreateKeyEx( key,
84                     subkey,
85                     0,
86                     NULL,
87                     REG_OPTION_NON_VOLATILE,
88                     KEY_WRITE,
89                     NULL,
90                     &hkSub,
91                     NULL);
92
93     DWORD status = RegSetValueEx( hkSub, lhs, 0, REG_SZ, (const BYTE *)rhs, strlen(rhs)+1 );
94
95     if ( hkSub )
96         RegCloseKey( hkSub );
97
98     return (status == ERROR_SUCCESS);
99 }
100
101 static BOOL 
102 WriteExpandedRegistryString(HKEY key, TCHAR * subkey, LPTSTR lhs, LPTSTR rhs)
103 {
104     HKEY hkSub = NULL;
105     RegCreateKeyEx( key,
106                     subkey,
107                     0,
108                     NULL,
109                     REG_OPTION_NON_VOLATILE,
110                     KEY_WRITE,
111                     NULL,
112                     &hkSub,
113                     NULL);
114
115     DWORD status = RegSetValueEx( hkSub, lhs, 0, REG_EXPAND_SZ, (const BYTE *)rhs, strlen(rhs)+1 );
116
117     if ( hkSub )
118         RegCloseKey( hkSub );
119
120     return (status == ERROR_SUCCESS);
121 }
122
123 static BOOL 
124 ReadRegistryString(HKEY key, TCHAR * subkey, LPTSTR lhs, LPTSTR rhs, DWORD * size)
125 {
126     HKEY hkSub = NULL;
127     RegCreateKeyEx( key,
128                     subkey,
129                     0,
130                     NULL,
131                     REG_OPTION_NON_VOLATILE,
132                     KEY_READ,
133                     NULL,
134                     &hkSub,
135                     NULL);
136
137     DWORD dwType = 0;
138     DWORD localSize = *size;
139
140     DWORD status = RegQueryValueEx( hkSub, lhs, 0, &dwType, (LPBYTE)rhs, &localSize);
141     if (status == 0 && dwType == REG_EXPAND_SZ) {
142         TCHAR * buf = (TCHAR *)malloc((*size) * sizeof(TCHAR));
143         memcpy(buf, rhs, (*size) * sizeof(TCHAR));
144         localSize = ExpandEnvironmentStrings(buf, rhs, *size);
145         free(buf);
146         if ( localSize > *size )
147             status = !ERROR_SUCCESS;
148     }
149     *size = localSize;
150
151     if ( hkSub )
152         RegCloseKey( hkSub );
153
154     return (status == ERROR_SUCCESS);
155 }
156
157 static BOOL 
158 DeleteRegistryString(HKEY key, TCHAR * subkey, LPTSTR lhs)
159 {
160     HKEY hkSub = NULL;
161     RegCreateKeyEx( key,
162                     subkey,
163                     0,
164                     NULL,
165                     REG_OPTION_NON_VOLATILE,
166                     KEY_WRITE,
167                     NULL,
168                     &hkSub,
169                     NULL);
170
171     DWORD status = RegDeleteValue( hkSub, lhs );
172
173     if ( hkSub )
174         RegCloseKey( hkSub );
175
176     return (status == ERROR_SUCCESS);
177 }
178
179 /*
180  * STRINGS ____________________________________________________________________
181  *
182  */
183
184 static LPTSTR AllocateStringMemory (size_t cch)
185 {
186    LPTSTR psz = (LPTSTR)Allocate (sizeof(TCHAR) * (cch+1));
187    memset (psz, 0x00, sizeof(TCHAR) * (cch+1));
188    return psz;
189 }
190
191 static void FreeStringMemory (LPTSTR pszString)
192 {
193    Free (pszString);
194 }
195
196 static int lstrncmpi (LPCTSTR pszA, LPCTSTR pszB, size_t cch)
197 {
198    if (!pszA || !pszB)
199       {
200       return (!pszB) - (!pszA);   // A,!B:1, !A,B:-1, !A,!B:0
201       }
202
203    for ( ; cch > 0; cch--, pszA = CharNext(pszA), pszB = CharNext(pszB))
204       {
205       TCHAR chA = toupper( *pszA );
206       TCHAR chB = toupper( *pszB );
207
208       if (!chA || !chB)
209          return (!chB) - (!chA);    // A,!B:1, !A,B:-1, !A,!B:0
210
211       if (chA != chB)
212          return (int)(chA) - (int)(chB);   // -1:A<B, 0:A==B, 1:A>B
213       }
214
215    return 0;  // no differences before told to stop comparing, so A==B
216 }
217
218
219 /*
220  * REALLOC ____________________________________________________________________
221  *
222  */
223
224 #ifndef REALLOC
225 #define REALLOC(_a,_c,_r,_i) DriveMapReallocFunction ((LPVOID*)&_a,sizeof(*_a),&_c,_r,_i)
226 BOOL DriveMapReallocFunction (LPVOID *ppTarget, size_t cbElement, size_t *pcTarget, size_t cReq, size_t cInc)
227 {
228    LPVOID pNew;
229    size_t cNew;
230
231    if (cReq <= *pcTarget)
232       return TRUE;
233
234    if ((cNew = cInc * ((cReq + cInc-1) / cInc)) <= 0)
235       return FALSE;
236
237    if ((pNew = Allocate (cbElement * cNew)) == NULL)
238       return FALSE;
239    memset (pNew, 0x00, cbElement * cNew);
240
241    if (*pcTarget != 0)
242    {
243       memcpy (pNew, *ppTarget, cbElement * (*pcTarget));
244       Free (*ppTarget);
245    }
246
247    *ppTarget = pNew;
248    *pcTarget = cNew;
249    return TRUE;
250 }
251 #endif
252
253
254 /*
255  * WINDOWS NT STUFF ___________________________________________________________
256  *
257  */
258
259 static BOOL IsWindowsNT (void)
260 {
261    static BOOL fChecked = FALSE;
262    static BOOL fIsWinNT = FALSE;
263
264    if (!fChecked)
265       {
266       fChecked = TRUE;
267
268       OSVERSIONINFO Version;
269       memset (&Version, 0x00, sizeof(Version));
270       Version.dwOSVersionInfoSize = sizeof(Version);
271
272       if (GetVersionEx (&Version))
273          {
274          if (Version.dwPlatformId == VER_PLATFORM_WIN32_NT)
275             fIsWinNT = TRUE;
276          }
277       }
278
279    return fIsWinNT;
280 }
281
282 /* Check if the OS is Windows 2000 or higher.
283 */
284 BOOL IsWindows2000 (void)
285 {
286    static BOOL fChecked = FALSE;
287    static BOOL fIsWin2K = FALSE;
288
289    if (!fChecked)
290       {
291       fChecked = TRUE;
292
293       OSVERSIONINFO Version;
294       memset (&Version, 0x00, sizeof(Version));
295       Version.dwOSVersionInfoSize = sizeof(Version);
296
297       if (GetVersionEx (&Version))
298          {
299          if (Version.dwPlatformId == VER_PLATFORM_WIN32_NT &&
300              Version.dwMajorVersion >= 5)
301              fIsWin2K = TRUE;
302          }
303       }
304
305    return fIsWin2K;
306 }
307
308 /*
309  * GENERAL ____________________________________________________________________
310  *
311  */
312
313 void GetClientNetbiosName (LPTSTR pszName)
314 {
315     static TCHAR szNetbiosName[32] = "";
316
317     if ( szNetbiosName[0] == 0 ) {
318         lana_GetNetbiosName(szNetbiosName, LANA_NETBIOS_NAME_FULL);
319     }
320     _tcscpy(pszName, szNetbiosName);
321 }
322
323
324 BOOL SubmountToPath (PDRIVEMAPLIST pList, LPTSTR pszPath, LPTSTR pszSubmount, BOOL fMarkInUse)
325 {
326    // We can't do this translation unless we're under Windows NT.
327    //
328    if (!IsWindowsNT())
329       return FALSE;
330
331    // \\computer-afs\all always maps to "/afs"
332    //
333    if (!lstrcmpi (pszSubmount, TEXT("all")))
334       {
335       lstrcpy (pszPath, cm_slash_mount_root);
336       return TRUE;
337       }
338
339    // Otherwise, look up our list of submounts.
340    //
341 #ifdef AFSIFS
342     AdjustAfsPath (pszPath, pszSubmount, TRUE, TRUE);
343 #endif
344     for (size_t ii = 0; ii < pList->cSubmounts; ++ii)
345     {
346         BOOL b;
347 #ifndef AFSIFS
348         b = !lstrcmpi (pList->aSubmounts[ii].szSubmount, pszSubmount);
349 #else
350         b = !lstrcmpi (pList->aSubmounts[ii].szMapping, pszPath);
351 #endif
352         if (b)
353         {
354             if (fMarkInUse)
355                 pList->aSubmounts[ii].fInUse = TRUE;
356             AdjustAfsPath (pszPath, pList->aSubmounts[ii].szMapping, TRUE, TRUE);
357             return TRUE;
358         }
359     }
360
361     return FALSE;
362 }
363
364
365 BOOL IsValidSubmountName (LPTSTR pszSubmount)
366 {
367    if (!*pszSubmount)
368       return FALSE;
369    if (lstrlen (pszSubmount) > 12)
370       return FALSE;
371
372    for ( ; *pszSubmount; ++pszSubmount)
373    {
374        if (!isprint(*pszSubmount))
375            return FALSE;
376        if (*pszSubmount == TEXT(' '))
377            return FALSE;
378        if (*pszSubmount == TEXT('/'))
379            return FALSE;
380        if (*pszSubmount == TEXT('\\'))
381            return FALSE;
382        if (*pszSubmount == TEXT('\t'))
383            return FALSE;
384    }
385
386    return TRUE;
387 }
388
389
390 /*
391  * PIOCTL SUPPORT _____________________________________________________________
392  *
393  */
394
395 extern "C" {
396
397 #include "../afsd/fs_utils.h"
398
399 #define __CM_CONFIG_INTERFACES_ONLY__
400 #include "../afsd/cm_config.h"
401
402 #define __CM_IOCTL_INTERFACES_ONLY__
403 #include "../afsd/cm_ioctl.h"
404
405 } // extern "C"
406
407 #define PIOCTL_MAXSIZE     2048
408
409
410 BOOL fCanIssuePIOCTL (void)
411 {
412    if (!IsWindowsNT())
413       {
414       TCHAR szGateway[ 256 ] = TEXT("");
415       GetClientNetbiosName (szGateway);
416       return (szGateway[0]) ? TRUE : FALSE;
417       }
418
419    SERVICE_STATUS Status;
420    memset (&Status, 0x00, sizeof(Status));
421    Status.dwCurrentState = SERVICE_STOPPED;
422
423    SC_HANDLE hManager;
424    if ((hManager = OpenSCManager (NULL, NULL, GENERIC_READ)) != NULL)
425       {
426       SC_HANDLE hService;
427       if ((hService = OpenService (hManager, TEXT("TransarcAFSDaemon"), GENERIC_READ)) != NULL)
428          {
429          QueryServiceStatus (hService, &Status);
430          CloseServiceHandle (hService);
431          }
432
433       CloseServiceHandle (hManager);
434       }
435
436    return (Status.dwCurrentState == SERVICE_RUNNING) ? TRUE : FALSE;
437 }
438
439
440 /*
441  * QUERYDRIVEMAPLIST __________________________________________________________
442  *
443  */
444
445 void QueryDriveMapList_ReadSubmounts (PDRIVEMAPLIST pList)
446 {
447     if (IsWindowsNT())
448     {
449         HKEY hkSubmounts;
450
451         RegCreateKeyEx( HKEY_LOCAL_MACHINE, 
452                         cszSECTION_SUBMOUNTS,
453                         0, 
454                         "AFS", 
455                         REG_OPTION_NON_VOLATILE,
456                         KEY_READ|KEY_QUERY_VALUE,
457                         NULL, 
458                         &hkSubmounts,
459                         NULL );
460
461         DWORD dwSubmounts;
462         RegQueryInfoKey( hkSubmounts,
463                          NULL,  /* lpClass */
464                          NULL,  /* lpcClass */
465                          NULL,  /* lpReserved */
466                          NULL,  /* lpcSubKeys */
467                          NULL,  /* lpcMaxSubKeyLen */
468                          NULL,  /* lpcMaxClassLen */
469                          &dwSubmounts, /* lpcValues */
470                          NULL,  /* lpcMaxValueNameLen */
471                          NULL,  /* lpcMaxValueLen */
472                          NULL,  /* lpcbSecurityDescriptor */
473                          NULL   /* lpftLastWriteTime */
474                          );
475
476         for ( DWORD dwIndex = 0; dwIndex < dwSubmounts; dwIndex ++ ) {
477             TCHAR submountPath[MAX_PATH] = "";
478             DWORD submountPathLen = MAX_PATH;
479             TCHAR submountName[MAX_PATH];
480             DWORD submountNameLen = MAX_PATH;
481             DWORD dwType = 0;
482
483             RegEnumValue( hkSubmounts, dwIndex, submountName, &submountNameLen, NULL,
484                           &dwType, (LPBYTE)submountPath, &submountPathLen);
485
486             if (dwType == REG_EXPAND_SZ) {
487                 char buf[MAX_PATH];
488                 StringCbCopyA(buf, MAX_PATH, submountPath);
489                 submountPathLen = ExpandEnvironmentStrings(buf, submountPath, MAX_PATH);
490                 if (submountPathLen > MAX_PATH)
491                     continue;
492             }
493
494             SUBMOUNT Submount;
495             memset (&Submount, 0x00, sizeof(SUBMOUNT));
496             lstrcpy (Submount.szSubmount, submountName);
497
498             if ( submountPath[0] != TEXT('\0') ) {
499                 AdjustAfsPath (Submount.szMapping, submountPath, FALSE, TRUE);
500
501                 for (size_t ii = 0; ii < pList->cSubmounts; ++ii)
502                 {
503                     if (!pList->aSubmounts[ii].szSubmount[0])
504                         break;
505                 }
506                 if (REALLOC (pList->aSubmounts, pList->cSubmounts, 1+ii, cREALLOC_SUBMOUNTS))
507                 {
508                     memcpy (&pList->aSubmounts[ii], &Submount, sizeof(SUBMOUNT));
509                 }
510             }
511
512         }
513         RegCloseKey(hkSubmounts);
514     }
515 }
516
517
518 void QueryDriveMapList_ReadMappings (PDRIVEMAPLIST pList)
519 {
520     HKEY hkMappings;
521     RegCreateKeyEx( HKEY_CURRENT_USER,
522                     cszSECTION_MAPPINGS,
523                     0, 
524                     "AFS", 
525                     REG_OPTION_NON_VOLATILE,
526                     KEY_READ|KEY_QUERY_VALUE,
527                     NULL, 
528                     &hkMappings,
529                     NULL );
530
531     DWORD dwMappings;
532     RegQueryInfoKey( hkMappings,
533                      NULL,  /* lpClass */
534                      NULL,  /* lpcClass */
535                      NULL,  /* lpReserved */
536                      NULL,  /* lpcSubKeys */
537                      NULL,  /* lpcMaxSubKeyLen */
538                      NULL,  /* lpcMaxClassLen */
539                      &dwMappings, /* lpcValues */
540                      NULL,  /* lpcMaxValueNameLen */
541                      NULL,  /* lpcMaxValueLen */
542                      NULL,  /* lpcbSecurityDescriptor */
543                      NULL   /* lpftLastWriteTime */
544                      );
545
546     for ( DWORD dwIndex = 0; dwIndex < dwMappings; dwIndex ++ ) {
547         TCHAR mapping[MAX_PATH] = "";
548         DWORD mappingLen = MAX_PATH;
549         TCHAR drive[MAX_PATH];
550         DWORD driveLen = MAX_PATH;
551         DWORD dwType;
552
553         RegEnumValue( hkMappings, dwIndex, drive, &driveLen, NULL,
554                       &dwType, (LPBYTE)mapping, &mappingLen);
555         if ( dwType == REG_EXPAND_SZ ) {
556             TCHAR buf[MAX_PATH];
557             DWORD dummyLen = ExpandEnvironmentStrings(mapping, buf, MAX_PATH);
558             if (dummyLen > MAX_PATH)
559                 continue;
560             _tcsncpy(mapping, buf, MAX_PATH);
561         }
562
563         DRIVEMAP DriveMap;
564         memset (&DriveMap, 0x00, sizeof(DRIVEMAP));
565         DriveMap.chDrive = toupper(*drive);
566         DriveMap.fPersistent = TRUE;
567         if ((DriveMap.chDrive < chDRIVE_A) || (DriveMap.chDrive > chDRIVE_Z))
568             continue;
569
570        if (mapping[0] != TEXT('\0'))
571        {
572            AdjustAfsPath (DriveMap.szMapping, mapping, TRUE, TRUE);
573            if (DriveMap.szMapping[ lstrlen(DriveMap.szMapping)-1 ] == TEXT('*'))
574            {
575                DriveMap.fPersistent = FALSE;
576                DriveMap.szMapping[ lstrlen(DriveMap.szMapping)-1 ] = TEXT('\0');
577            }
578            size_t iDrive = DriveMap.chDrive - chDRIVE_A;
579            memcpy (&pList->aDriveMap[ iDrive ], &DriveMap, sizeof(DRIVEMAP));
580        }
581     }
582
583     RegCloseKey(hkMappings);
584 }
585
586 BOOL ForceMapActive (TCHAR chDrive)
587 {
588     TCHAR szDrive[2];
589     TCHAR szActive[32];
590
591     szDrive[0] = chDrive;
592     szDrive[1] = 0;
593
594     DWORD len = sizeof(szActive);
595     ReadRegistryString( HKEY_CURRENT_USER, cszSECTION_ACTIVE, szDrive, szActive, &len);
596
597     if ( !lstrcmp(szActive,"1") || !lstrcmpi(szActive,"true") || !lstrcmpi(szActive,"on") || !lstrcmpi(szActive,"yes") )
598         return TRUE;
599     return FALSE;
600 }
601
602
603 void WriteActiveMap (TCHAR chDrive, BOOL on)
604 {
605     TCHAR szDrive[2];
606
607     szDrive[0] = chDrive;
608     szDrive[1] = 0;
609
610     WriteRegistryString(HKEY_CURRENT_USER, cszSECTION_ACTIVE, szDrive, on ? "1" : "0");
611 }
612
613 void QueryDriveMapList_WriteMappings (PDRIVEMAPLIST pList)
614 {
615     WriteDriveMappings (pList);
616 }
617
618
619 void WriteDriveMappings (PDRIVEMAPLIST pList)
620 {
621     HKEY hkMappings;
622     RegCreateKeyEx( HKEY_CURRENT_USER, 
623                     cszSECTION_MAPPINGS,
624                     0, 
625                     "AFS", 
626                     REG_OPTION_NON_VOLATILE,
627                     KEY_READ|KEY_QUERY_VALUE|KEY_WRITE,
628                     NULL, 
629                     &hkMappings,
630                     NULL );
631
632     DWORD dwMappings;
633     RegQueryInfoKey( hkMappings,
634                      NULL,  /* lpClass */
635                      NULL,  /* lpcClass */
636                      NULL,  /* lpReserved */
637                      NULL,  /* lpcSubKeys */
638                      NULL,  /* lpcMaxSubKeyLen */
639                      NULL,  /* lpcMaxClassLen */
640                      &dwMappings, /* lpcValues */
641                      NULL,  /* lpcMaxValueNameLen */
642                      NULL,  /* lpcMaxValueLen */
643                      NULL,  /* lpcbSecurityDescriptor */
644                      NULL   /* lpftLastWriteTime */
645                      );
646
647     if ( dwMappings > 0 ) {
648         for ( long dwIndex = dwMappings - 1; dwIndex >= 0; dwIndex-- ) {
649             TCHAR drive[MAX_PATH];
650             DWORD driveLen = MAX_PATH;
651
652             RegEnumValue( hkMappings, dwIndex, drive, &driveLen, NULL, NULL, NULL, NULL);
653             RegDeleteValue( hkMappings, drive );
654         }
655     }
656
657    for (size_t iDrive = 0; iDrive < 26; ++iDrive)
658    {
659        if (pList->aDriveMap[iDrive].szMapping[0] != TEXT('\0'))
660        {
661            TCHAR szLHS[] = TEXT("*");
662            szLHS[0] = pList->aDriveMap[iDrive].chDrive;
663
664            TCHAR szRHS[MAX_PATH];
665            AdjustAfsPath (szRHS, pList->aDriveMap[iDrive].szMapping, TRUE, TRUE);
666            if (!pList->aDriveMap[iDrive].fPersistent)
667                lstrcat (szRHS, TEXT("*"));
668
669            RegSetValueEx( hkMappings, szLHS, 0, REG_EXPAND_SZ, (const BYTE *)szRHS, lstrlen(szRHS) + 1);
670        }
671    }
672    RegCloseKey( hkMappings );
673 }
674
675 BOOL DriveIsGlobalAfsDrive(TCHAR chDrive)
676 {
677    TCHAR szKeyName[128];
678    TCHAR szValueName[128];
679    TCHAR szValue[128];
680    HKEY hKey;
681
682    _stprintf(szKeyName, TEXT("%s\\GlobalAutoMapper"), AFSREG_CLT_SVC_PARAM_SUBKEY);
683
684    if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, szKeyName, 0, KEY_QUERY_VALUE, &hKey) != ERROR_SUCCESS)
685       return FALSE;
686
687    _stprintf(szValueName, TEXT("%c:"), chDrive);
688
689    DWORD dwSize = sizeof(szValue);
690    BOOL bIsGlobal = (RegQueryValueEx (hKey, szValueName, NULL, NULL, (PBYTE)szValue, &dwSize) == ERROR_SUCCESS);
691
692    RegCloseKey (hKey);
693    
694    return bIsGlobal;
695 }
696
697
698 void QueryDriveMapList_FindNetworkDrives (PDRIVEMAPLIST pList, BOOL *pfFoundNew)
699 {
700    for (TCHAR chDrive = chDRIVE_A; chDrive <= chDRIVE_Z; ++chDrive)
701       {
702       TCHAR szSubmount[ MAX_PATH ];
703       if (!GetDriveSubmount (chDrive, szSubmount))
704          continue;
705
706       // We've got a mapping!  Drive {chDrive} is mapped to submount
707       // {szSubmount}. See if that submount makes sense.
708       //
709       if (!IsWindowsNT())
710          {
711          size_t iDrive = chDrive - chDRIVE_A;
712          if (pList->aDriveMap[ iDrive ].szMapping[0] != TEXT('\0'))
713             {
714             pList->aDriveMap[ iDrive ].fActive = TRUE;
715             lstrcpy (pList->aDriveMap[ iDrive ].szSubmount, szSubmount);
716             }
717          continue;
718          }
719       else // (IsWindowsNT())
720          {
721          TCHAR szAfsPath[ MAX_PATH ];
722          if (!SubmountToPath (pList, szAfsPath, szSubmount, TRUE))
723             continue;
724
725          // Okay, we know that drive {chDrive} is mapped to afs path {szAfsPath}.
726          // If this drive is a global afs drive, then reject it.  Otherwise, look 
727          // at pList->aDriveMap, to see if this drive mapping is already in our 
728          // list. If not, add it and set pfFoundNew.
729          //
730          if (DriveIsGlobalAfsDrive(chDrive))
731             continue;
732          
733          size_t iDrive = chDrive - chDRIVE_A;
734          if (lstrcmpi (pList->aDriveMap[ iDrive ].szMapping, szAfsPath))
735             {
736             *pfFoundNew = TRUE;
737             pList->aDriveMap[ iDrive ].fPersistent = TRUE;
738             }
739          pList->aDriveMap[ iDrive ].fActive = TRUE;
740          pList->aDriveMap[ iDrive ].chDrive = chDrive;
741          lstrcpy (pList->aDriveMap[ iDrive ].szSubmount, szSubmount);
742          AdjustAfsPath (pList->aDriveMap[ iDrive ].szMapping, szAfsPath, TRUE, TRUE);
743          }
744       }
745 }
746
747
748 void QueryDriveMapList (PDRIVEMAPLIST pList)
749 {
750    // Initialize the data structure
751    //
752    memset (pList, 0x00, sizeof(DRIVEMAPLIST));
753    for (size_t ii = 0; ii < 26; ++ii)
754       pList->aDriveMap[ii].chDrive = chDRIVE_A + ii;
755
756    // Read the current lists of submounts and drive letter mappings
757    //
758    QueryDriveMapList_ReadSubmounts (pList);
759    QueryDriveMapList_ReadMappings (pList);
760
761    // Look through the current list of network drives, and see if
762    // any are currently mapped to AFS. If we find any which are mapped
763    // into AFS unexpectedly, we'll have to rewrite the mappings list.
764    //
765    BOOL fFoundNew = FALSE;
766    QueryDriveMapList_FindNetworkDrives (pList, &fFoundNew);
767
768    if (fFoundNew)
769       {
770       QueryDriveMapList_WriteMappings (pList);
771       }
772 }
773
774
775 void FreeDriveMapList (PDRIVEMAPLIST pList)
776 {
777    if (pList->aSubmounts)
778       Free (pList->aSubmounts);
779    memset (pList, 0x00, sizeof(DRIVEMAPLIST));
780 }
781
782
783 BOOL PathToSubmount (LPTSTR pszSubmount, LPTSTR pszMapping, LPTSTR pszSubmountReq, ULONG *pStatus)
784 {
785    if (pszSubmountReq && !IsValidSubmountName (pszSubmountReq))
786       pszSubmountReq = NULL;
787
788    TCHAR szAfsPath[ MAX_PATH ];
789    AdjustAfsPath (szAfsPath, pszMapping, TRUE, TRUE);
790
791    // Try to ask AFSD for a new submount name.
792    //
793    if (!fCanIssuePIOCTL())
794       return FALSE;
795
796    BYTE InData[ PIOCTL_MAXSIZE ];
797    memset (InData, 0x00, sizeof(InData));
798
799    LPTSTR pszInData = (LPTSTR)InData;
800    lstrcpy (pszInData, pszMapping);
801    pszInData += 1+lstrlen(pszInData);
802    if (pszSubmountReq)
803       lstrcpy (pszInData, pszSubmountReq);
804
805    BYTE OutData[ PIOCTL_MAXSIZE ];
806    memset (OutData, 0x00, sizeof(OutData));
807
808    struct ViceIoctl IOInfo;
809    IOInfo.in = (char *)InData;
810    IOInfo.in_size = PIOCTL_MAXSIZE;
811    IOInfo.out = (char *)OutData;
812    IOInfo.out_size = PIOCTL_MAXSIZE;
813
814    ULONG status = pioctl (0, VIOC_MAKESUBMOUNT, &IOInfo, 1);
815    if (pStatus)
816        *pStatus = status;
817
818    if (status)
819       return FALSE;
820
821    lstrcpy (pszSubmount, (LPCTSTR)OutData);
822    return (pszSubmount[0] != TEXT('\0')) ? TRUE : FALSE;
823 }
824
825
826 BOOL ActivateDriveMap (TCHAR chDrive, LPTSTR pszMapping, LPTSTR pszSubmountReq, BOOL fPersistent, DWORD *pdwStatus)
827 {
828    // We can only map drives to places in AFS using this function.
829    //
830    if ( (lstrncmpi (pszMapping, cm_slash_mount_root, lstrlen(cm_slash_mount_root))) &&
831         (lstrncmpi (pszMapping, cm_back_slash_mount_root, lstrlen(cm_back_slash_mount_root))) )
832       {
833       if (pdwStatus)
834          *pdwStatus = ERROR_BAD_NETPATH;
835       return FALSE;
836       }
837
838    // First we have to translate {pszMapping} into a submount, and if there is
839    // no current submount associated with this path, we'll have to make one.
840    //
841    ULONG status;
842    TCHAR szSubmount[ MAX_PATH ];
843    if (!PathToSubmount (szSubmount, pszMapping, pszSubmountReq, &status))
844       {
845       if (pdwStatus)
846          *pdwStatus = status;
847       return FALSE;
848       }
849
850    // We now have a submount name and drive letter--map the network drive.
851     DWORD rc;
852 #ifndef AFSIFS
853     rc=MountDOSDrive(chDrive,szSubmount,fPersistent,NULL);
854 #else
855     rc=MountDOSDrive(chDrive,/*szSubmount*/pszMapping,fPersistent,NULL);
856 #endif
857     if (rc == NO_ERROR)
858         return TRUE;
859
860     if (pdwStatus)
861         *pdwStatus = rc;
862     return FALSE;
863 }
864
865
866 BOOL InactivateDriveMap (TCHAR chDrive, DWORD *pdwStatus)
867 {
868     DWORD rc = DisMountDOSDrive(chDrive, FALSE);
869     if (rc == NO_ERROR)
870         return TRUE;
871
872     if (pdwStatus)
873         *pdwStatus = rc;
874     return FALSE;
875 }
876
877
878 void AddSubMount (LPTSTR pszSubmount, LPTSTR pszMapping)
879 {
880     TCHAR szRHS[ MAX_PATH ];
881     AdjustAfsPath (szRHS, pszMapping, FALSE, TRUE);
882     if (!szRHS[0])
883         lstrcpy (szRHS, TEXT("/"));
884
885     WriteExpandedRegistryString(HKEY_LOCAL_MACHINE, cszSECTION_SUBMOUNTS, pszSubmount, szRHS);
886 }
887
888
889 void RemoveSubMount (LPTSTR pszSubmount)
890 {
891     DeleteRegistryString(HKEY_LOCAL_MACHINE, cszSECTION_SUBMOUNTS, pszSubmount);
892 }
893
894
895 void AdjustAfsPath (LPTSTR pszTarget, LPCTSTR pszSource, BOOL fWantAFS, BOOL fWantForwardSlashes)
896 {
897     if (!*pszSource)
898         lstrcpy (pszTarget, (fWantAFS) ? cm_slash_mount_root : TEXT(""));
899     else if ((*pszSource != TEXT('/')) && (*pszSource != TEXT('\\')))
900         wsprintf (pszTarget, TEXT("%s/%s"),cm_slash_mount_root, pszSource);
901     // We don't want to strip afs off the start if it is part of something for example afscell.company.com
902     else if (fWantAFS && (lstrncmpi (&pszSource[1], cm_mount_root, strlen(cm_mount_root))) || !((pszSource[strlen(cm_slash_mount_root)] == TEXT('/')) ||
903                                                                                                  (pszSource[strlen(cm_slash_mount_root)] == TEXT('\\')) ||
904                                                                                                  (lstrlen(pszSource) == strlen(cm_slash_mount_root))))
905         wsprintf (pszTarget, TEXT("%s%s"),cm_slash_mount_root, pszSource);
906     else if (!fWantAFS && (!lstrncmpi (&pszSource[1], cm_mount_root, strlen(cm_mount_root)) && ((pszSource[strlen(cm_slash_mount_root)] == TEXT('/')) ||
907                                                                                                  (pszSource[strlen(cm_slash_mount_root)] == TEXT('\\')) ||
908                                                                                                  (lstrlen(pszSource) == strlen(cm_slash_mount_root)))))
909         lstrcpy (pszTarget, &pszSource[strlen(cm_slash_mount_root)]);
910     else
911         lstrcpy (pszTarget, pszSource);
912
913    for (LPTSTR pch = pszTarget; *pch; ++pch)
914       {
915       if (fWantForwardSlashes)
916          {
917          *pch = (*pch == TEXT('\\')) ? TEXT('/') : (*pch);
918          }
919       else // (!fWantForwardSlashes)
920          {
921          *pch = (*pch == TEXT('/')) ? TEXT('\\') : (*pch);
922          }
923       }
924
925    if (lstrlen(pszTarget) &&
926        ((pszTarget[lstrlen(pszTarget)-1] == TEXT('/')) ||
927         (pszTarget[lstrlen(pszTarget)-1] == TEXT('\\'))))
928       {
929       pszTarget[lstrlen(pszTarget)-1] = TEXT('\0');
930       }
931 }
932
933 BOOL GetDriveSubmount (TCHAR chDrive, LPTSTR pszSubmountNow)
934 {
935         BOOL isWinNT = IsWindowsNT();
936
937         TCHAR szDrive[] = TEXT("*:");
938     szDrive[0] = chDrive;
939
940     TCHAR szMapping[ _MAX_PATH ] = TEXT("");
941
942     if (isWinNT && !QueryDosDevice (szDrive, szMapping, MAX_PATH))
943            return FALSE;
944
945     LPTSTR pszSubmount = szMapping;
946     
947         TCHAR szNetBiosName[32];
948     memset(szNetBiosName, '\0', sizeof(szNetBiosName));
949     GetClientNetbiosName(szNetBiosName);
950     _tcscat(szNetBiosName, TEXT("\\"));
951
952    if (isWinNT)
953    {
954       // Now if this is an AFS network drive mapping, {szMapping} will be:
955       //
956       //   \Device\LanmanRedirector\<Drive>:\<netbiosname>\submount
957       //
958       // on Windows NT. On Windows 2000, it will be:
959       //
960       //   \Device\LanmanRedirector\;<Drive>:0\<netbiosname>\submount
961       //
962       // (This is presumably to support multiple drive mappings with
963       // Terminal Server).
964       //
965       // on Windows XP and 2003, it will be :
966       //   \Device\LanmanRedirector\;<Drive>:<AuthID>\<netbiosname>\submount
967       //
968       //   where : <Drive> : DOS drive letter
969       //           <AuthID>: Authentication ID, 16 char hex.
970       //           <netbiosname>: Netbios name of server
971       //
972       BOOL b;
973 #ifndef AFSIFS
974       b = _tcsnicmp(szMapping, cszLANMANDEVICE, _tcslen(cszLANMANDEVICE));
975 #else
976       const TCHAR ker_sub_path[] = "\\Device\\afsrdr\\";
977       b = _tcsnicmp(szMapping, ker_sub_path, _tcslen(ker_sub_path));
978 #endif
979        if (b)
980          return FALSE;
981 #ifndef AFSIFS
982       pszSubmount = &szMapping[ _tcslen(cszLANMANDEVICE) ];
983 #else
984       pszSubmount = &szMapping[ _tcslen(ker_sub_path) ];
985 #endif
986
987 #ifdef AFSIFS
988        if (*(pszSubmount) < '0' ||
989             *(pszSubmount) > '9')
990            return FALSE;
991        ++pszSubmount;
992 #else   
993       if (IsWindows2000())
994       {
995           if (*(pszSubmount) != TEXT(';'))
996              return FALSE;
997       } else 
998           --pszSubmount;
999
1000       if (toupper(*(++pszSubmount)) != chDrive)
1001          return FALSE;
1002
1003       if (*(++pszSubmount) != TEXT(':'))
1004          return FALSE;
1005
1006 #ifdef COMMENT
1007        // No longer a safe assumption on XP
1008       if (IsWindows2000())
1009           if (*(++pszSubmount) != TEXT('0'))
1010              return FALSE;
1011 #endif
1012
1013       // scan for next "\"
1014       while (*(++pszSubmount) != TEXT('\\'))
1015       {
1016           if (*pszSubmount==0)
1017               return FALSE;
1018       }
1019
1020        // note that szNetBiosName has a '\\' tagged in the end earlier
1021       for (++pszSubmount; *pszSubmount && (*pszSubmount != TEXT('\\')); ++pszSubmount)
1022          if (!_tcsncicmp(pszSubmount, szNetBiosName, _tcslen(szNetBiosName)))
1023             break;
1024       if ((!*pszSubmount) || (*pszSubmount == TEXT('\\')))
1025          return FALSE;
1026
1027        pszSubmount += _tcslen(szNetBiosName);
1028 #endif
1029       }
1030    else // (!IsWindowsNT())
1031       {
1032       DWORD dwSize = MAX_PATH;
1033       if (WNetGetConnection (szDrive, szMapping, &dwSize) != NO_ERROR)
1034          return FALSE;
1035       if (*(pszSubmount++) != TEXT('\\'))
1036          return FALSE;
1037       if (*(pszSubmount++) != TEXT('\\'))
1038          return FALSE;
1039       for ( ; *pszSubmount && (*pszSubmount != TEXT('\\')); ++pszSubmount)
1040          if (!lstrncmpi (pszSubmount, szNetBiosName, lstrlen(szNetBiosName)))
1041             break;
1042       if ((!*pszSubmount) || (*pszSubmount == TEXT('\\')))
1043          return FALSE;
1044       pszSubmount += lstrlen(szNetBiosName);
1045       }
1046
1047    if (!pszSubmount || !*pszSubmount)
1048       return FALSE;
1049
1050 #ifndef AFSIFS
1051    lstrcpy (pszSubmountNow, pszSubmount);
1052 #else
1053    lstrcpy (pszSubmountNow, "\\afs");
1054    lstrcat (pszSubmountNow, pszSubmount);
1055 #endif
1056    return TRUE;
1057 }
1058
1059 /* Generate Random User name random acording to time*/
1060 DWORD dwOldState=0;
1061 TCHAR pUserName[MAXRANDOMNAMELEN]=TEXT("");
1062 BOOL fUserName=FALSE;
1063 #define AFSLogonOptionName TEXT(AFSREG_CLT_SVC_PROVIDER_SUBKEY)
1064
1065 void SetBitLogonOption(BOOL set,DWORD value)
1066 {
1067
1068    RWLogonOption(FALSE,((set)?value | RWLogonOption(TRUE,0):RWLogonOption(TRUE,0) & ~value) );  
1069 }
1070
1071 DWORD RWLogonOption(BOOL read,DWORD value)
1072 {
1073     // if read is true then if value==0 return registry value
1074     // if read and value!=0 then use value to test registry, return TRUE if value bits match value read
1075     HKEY hk;
1076     DWORD dwDisp;
1077     DWORD LSPtype, LSPsize;
1078     DWORD rval;
1079    
1080     if (read)
1081     {
1082         rval=0;
1083         if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, AFSLogonOptionName, 0, KEY_QUERY_VALUE, &hk)==ERROR_SUCCESS)
1084         {
1085             LSPsize=sizeof(rval);
1086             RegQueryValueEx(hk, "LogonOptions", NULL,
1087                              &LSPtype, (LPBYTE)&rval, &LSPsize);
1088             RegCloseKey (hk);
1089         }
1090         return (value==0)?rval:((rval & value)==value);
1091     } else {    //write
1092         if (RegCreateKeyEx (HKEY_LOCAL_MACHINE, AFSLogonOptionName, 0, NULL, 0, KEY_SET_VALUE, NULL, &hk, &dwDisp) == ERROR_SUCCESS)
1093         {
1094             RegSetValueEx(hk,TEXT("LogonOptions"),NULL,REG_DWORD,(LPBYTE)&value,sizeof(value));
1095             RegCloseKey (hk);
1096         }
1097         return TRUE;
1098     }    
1099 }
1100
1101 void MapShareName(char *pszCmdLineA)
1102 {
1103         fUserName = TRUE;
1104         TCHAR *p=pUserName;
1105         pszCmdLineA++;
1106         while (*pszCmdLineA && (*pszCmdLineA != ' '))
1107         {
1108           *p++=*pszCmdLineA++;
1109         }
1110 }
1111
1112 void GenRandomName(TCHAR *pname,int len)
1113 {
1114         if (fUserName)
1115         {               //user name was passed through command line, use once
1116                 fUserName=FALSE;
1117                 return;
1118         }
1119         srand( (unsigned)time( NULL ) );
1120         for (int i=0;i<len;i++)
1121                 pname[i]='a'+(rand() % 26);
1122         pname[len]=0;
1123         return;
1124 }
1125
1126 /*
1127         Make a connection using users name
1128         if fUserName then force a connection
1129 */
1130
1131 BOOL TestAndDoMapShare(DWORD dwState)
1132 {
1133     if ((dwState!=SERVICE_RUNNING) || (dwOldState!=SERVICE_START_PENDING))
1134         {
1135                 dwOldState=dwState;
1136                 return TRUE;
1137         }
1138         dwOldState=SERVICE_RUNNING;
1139         if (RWLogonOption(TRUE,LOGON_OPTION_HIGHSECURITY))
1140             return (DoMapShare() && GlobalMountDrive());
1141         return GlobalMountDrive();
1142 }
1143
1144 BOOL IsServiceActive()
1145 {
1146    SC_HANDLE hManager;
1147    SERVICE_STATUS Status;
1148    if ((hManager = OpenSCManager (NULL, NULL, GENERIC_READ)) != NULL)
1149       {
1150       SC_HANDLE hService;
1151       if ((hService = OpenService (hManager, TEXT("TransarcAFSDaemon"), GENERIC_READ)) != NULL)
1152          {
1153          QueryServiceStatus (hService, &Status);
1154          CloseServiceHandle (hService);
1155          }
1156
1157       CloseServiceHandle (hManager);
1158       }
1159
1160    return (Status.dwCurrentState == SERVICE_RUNNING) ? TRUE : FALSE;
1161 }
1162
1163 void TestAndDoUnMapShare()
1164 {
1165         if (!RWLogonOption(TRUE,LOGON_OPTION_HIGHSECURITY))
1166                 return;
1167         DoUnMapShare(FALSE);    
1168 }
1169
1170 void DoUnMapShare(BOOL drivemap)        //disconnect drivemap 
1171 {
1172         TCHAR szMachine[MAX_PATH],szPath[MAX_PATH];
1173         DWORD rc=28;
1174         HANDLE hEnum;
1175         LPNETRESOURCE lpnrLocal,lpnr=NULL;
1176         DWORD res;
1177         DWORD cbBuffer=16384;
1178         DWORD cEntries=-1;
1179         CHAR *pSubmount="";
1180
1181     memset(szMachine, '\0', sizeof(szMachine));
1182     GetClientNetbiosName(szMachine);
1183
1184    // Initialize the data structure
1185         if ((res=WNetOpenEnum(RESOURCE_CONNECTED,RESOURCETYPE_DISK,RESOURCEUSAGE_CONNECTABLE,lpnr,&hEnum))!=NO_ERROR)
1186                 return;
1187         sprintf(szPath,"\\\\%s\\",szMachine);
1188         _strlwr(szPath);
1189         lpnrLocal=(LPNETRESOURCE) GlobalAlloc(GPTR,cbBuffer);
1190         do {
1191                 memset(lpnrLocal,0,cbBuffer);
1192                 if ((res = WNetEnumResource(hEnum,&cEntries,lpnrLocal,&cbBuffer))==NO_ERROR)
1193                 {
1194                         for (DWORD i=0;i<cEntries;i++)
1195                         {
1196                                 if (strstr(_strlwr(lpnrLocal[i].lpRemoteName),szPath))
1197                                 {
1198                                         if ((lpnrLocal[i].lpLocalName) && (strlen(lpnrLocal[i].lpLocalName)>0))
1199                                         {
1200                                                 if (drivemap) {
1201                                                     DisMountDOSDrive(*lpnrLocal[i].lpLocalName);
1202                             DEBUG_EVENT1("AFS DriveUnMap","UnMap-Local=%x",res);
1203                         }
1204                                         } else {
1205                                             DisMountDOSDriveFull(lpnrLocal[i].lpRemoteName);
1206                         DEBUG_EVENT1("AFS DriveUnMap","UnMap-Remote=%x",res);
1207                     }
1208                                 }
1209                         }
1210                 }
1211         } while (res!=ERROR_NO_MORE_ITEMS);
1212         GlobalFree((HGLOBAL)lpnrLocal);
1213         WNetCloseEnum(hEnum);
1214 }
1215
1216 BOOL DoMapShareChange()
1217 {
1218         DRIVEMAPLIST List;
1219         TCHAR szMachine[ MAX_PATH],szPath[MAX_PATH];
1220         DWORD rc=28;
1221         HANDLE hEnum;
1222         LPNETRESOURCE lpnrLocal,lpnr=NULL;
1223         DWORD res;
1224         DWORD cEntries=-1;
1225     DWORD cbBuffer=16384;
1226
1227     memset(szMachine, '\0', sizeof(szMachine));
1228     GetClientNetbiosName(szMachine);
1229
1230     // Initialize the data structure
1231         if (!IsServiceActive())
1232                 return TRUE;
1233         memset (&List, 0x00, sizeof(DRIVEMAPLIST));
1234         for (size_t ii = 0; ii < 26; ++ii)
1235                 List.aDriveMap[ii].chDrive = chDRIVE_A + ii;
1236         QueryDriveMapList_ReadSubmounts (&List);
1237         if ((res=WNetOpenEnum(RESOURCE_CONNECTED,RESOURCETYPE_DISK,RESOURCEUSAGE_CONNECTABLE,lpnr,&hEnum))!=NO_ERROR)
1238                 return FALSE;
1239         lpnrLocal=(LPNETRESOURCE) GlobalAlloc(GPTR,cbBuffer);
1240         sprintf(szPath,"\\\\%s\\",szMachine);
1241         _strlwr(szPath);
1242         do {
1243                 memset(lpnrLocal,0,cbBuffer);
1244                 if ((res = WNetEnumResource(hEnum,&cEntries,lpnrLocal,&cbBuffer))==NO_ERROR)
1245                 {
1246                         for (DWORD i=0;i<cEntries;i++)
1247                         {
1248                                 if (strstr(_strlwr(lpnrLocal[i].lpRemoteName),szPath)==NULL)
1249                                         continue;       //only look at real afs mappings
1250                                 CHAR * pSubmount=strrchr(lpnrLocal[i].lpRemoteName,'\\')+1;
1251                                 if (lstrcmpi(pSubmount,"all")==0) 
1252                                         continue;                               // do not remove 'all'
1253                                 for (DWORD j=0;j<List.cSubmounts;j++)
1254                                 {
1255                                         if (
1256                                                 (List.aSubmounts[j].szSubmount[0]) &&
1257                                                 (lstrcmpi(List.aSubmounts[j].szSubmount,pSubmount)==0)
1258                                                 ) 
1259                                         {
1260                                                 List.aSubmounts[j].fInUse=TRUE; 
1261                                                 goto nextname;
1262                                         }
1263                                 }
1264                                 // wasn't on list so lets remove
1265                                 DisMountDOSDrive(pSubmount);
1266                                 nextname:;
1267                         }
1268                 }
1269         } while (res!=ERROR_NO_MORE_ITEMS);
1270         GlobalFree((HGLOBAL)lpnrLocal);
1271         WNetCloseEnum(hEnum);
1272         sprintf(szPath,"\\\\%s\\all",szMachine);
1273
1274         // Lets connect all submounts that weren't connectd
1275     DWORD cbUser=MAXRANDOMNAMELEN-1;
1276         CHAR szUser[MAXRANDOMNAMELEN];
1277     CHAR * pUser = NULL;
1278         if (WNetGetUser(szPath,(LPSTR)szUser,&cbUser)!=NO_ERROR) {
1279         if (RWLogonOption(TRUE,LOGON_OPTION_HIGHSECURITY)) {
1280             if (!pUserName[0]) {
1281                 GenRandomName(szUser,MAXRANDOMNAMELEN-1);
1282                 pUser = szUser;
1283             } else {
1284                 pUser = pUserName;
1285             }
1286         }
1287     } else {
1288                 if ((pUser=strchr(szUser,'\\'))!=NULL)
1289             pUser++;
1290         }
1291
1292     for (DWORD j=0;j<List.cSubmounts;j++)
1293         {
1294                 if (List.aSubmounts[j].fInUse)
1295                         continue;
1296                 DWORD res=MountDOSDrive(0,List.aSubmounts[j].szSubmount,FALSE,pUser);
1297         }
1298         return TRUE;
1299 }
1300
1301 BOOL DoMapShare()
1302 {
1303         DRIVEMAPLIST List;
1304         DWORD rc=28;
1305         BOOL bMappedAll=FALSE;
1306
1307    // Initialize the data structure
1308         DEBUG_EVENT0("AFS DoMapShare");
1309         QueryDriveMapList (&List);
1310         DoUnMapShare(TRUE);
1311         // All connections have been removed
1312         // Lets restore them after making the connection from the random name
1313
1314         TCHAR szMachine[ MAX_PATH],szPath[MAX_PATH];
1315     memset(szMachine, '\0', sizeof(szMachine));
1316     GetClientNetbiosName(szMachine);
1317     sprintf(szPath,"\\\\%s\\all",szMachine);
1318
1319     // Lets connect all submounts that weren't connectd
1320     DWORD cbUser=MAXRANDOMNAMELEN-1;
1321         CHAR szUser[MAXRANDOMNAMELEN];
1322     CHAR * pUser = NULL;
1323         if (WNetGetUser(szPath,(LPSTR)szUser,&cbUser)!=NO_ERROR) {
1324         if (RWLogonOption(TRUE,LOGON_OPTION_HIGHSECURITY)) {
1325             if (!pUserName[0]) {
1326                 GenRandomName(szUser,MAXRANDOMNAMELEN-1);
1327                 pUser = szUser;
1328             } else {
1329                 pUser = pUserName;
1330             }
1331         }
1332     } else {
1333                 if ((pUser=strchr(szUser,'\\'))!=NULL)
1334             pUser++;
1335         }
1336
1337         for (DWORD i=0;i<List.cSubmounts;i++)
1338         {
1339                 if (List.aSubmounts[i].szSubmount[0])
1340                 {
1341                         DWORD res=MountDOSDrive(0,List.aSubmounts[i].szSubmount,FALSE,pUser);
1342                         if (lstrcmpi("all",List.aSubmounts[i].szSubmount)==0)
1343                                 bMappedAll=TRUE;
1344                 }
1345         }
1346         if (!bMappedAll)        //make sure all is mapped also
1347         {
1348         DWORD res=MountDOSDrive(0,"all",FALSE,pUser);
1349         if (res==ERROR_SESSION_CREDENTIAL_CONFLICT)
1350         {
1351             DisMountDOSDrive("all");
1352             MountDOSDrive(0,"all",FALSE,pUser);
1353         }
1354         }
1355         for (TCHAR chDrive = chDRIVE_A; chDrive <= chDRIVE_Z; ++chDrive)
1356         {
1357                 if (List.aDriveMap[chDrive-chDRIVE_A].fActive ||
1358             ForceMapActive(chDrive))
1359                 {
1360             TCHAR szSubmount[ MAX_PATH ];
1361             if (List.aDriveMap[chDrive-chDRIVE_A].szSubmount[0])
1362                 lstrcpy(szSubmount,List.aDriveMap[chDrive-chDRIVE_A].szSubmount);
1363             else if (!PathToSubmount (szSubmount, List.aDriveMap[chDrive-chDRIVE_A].szMapping, NULL, NULL))
1364                 continue;
1365
1366             BOOL fPersistent = List.aDriveMap[chDrive-chDRIVE_A].fPersistent;
1367             if (RWLogonOption(TRUE,LOGON_OPTION_HIGHSECURITY))
1368                 fPersistent = FALSE;
1369                     DWORD res=MountDOSDrive(chDrive
1370                                             ,szSubmount
1371                                             ,fPersistent,pUser);
1372                 }
1373         }
1374         return TRUE;
1375 }
1376
1377 BOOL GlobalMountDrive()
1378 {
1379     char szDriveToMapTo[5];
1380     DWORD dwResult;
1381     char szKeyName[256];
1382     HKEY hKey;
1383     DWORD dwIndex = 0;
1384     DWORD dwDriveSize;
1385     DWORD dwSubMountSize;
1386     char unsigned szSubMount[256];
1387     char cm_HostName[200];
1388     DWORD dwType=sizeof(cm_HostName);
1389     if (!IsServiceActive())
1390         return TRUE;
1391     if (!GetComputerName(cm_HostName, &dwType))
1392         return TRUE;
1393     sprintf(szKeyName, "%s\\GlobalAutoMapper", AFSREG_CLT_SVC_PARAM_SUBKEY);
1394     
1395     dwResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE, szKeyName, 0, KEY_QUERY_VALUE,
1396                             &hKey);
1397     if (dwResult != ERROR_SUCCESS)
1398         return TRUE;
1399     
1400     while (1) {
1401         dwDriveSize = sizeof(szDriveToMapTo);
1402         dwSubMountSize = sizeof(szSubMount);
1403         dwResult = RegEnumValue(hKey, dwIndex++, szDriveToMapTo, &dwDriveSize, 
1404                                 0, &dwType, szSubMount, &dwSubMountSize);
1405         if (dwResult != ERROR_MORE_DATA) {
1406             if (dwResult != ERROR_SUCCESS) {
1407                 if (dwResult != ERROR_NO_MORE_ITEMS)
1408                 {
1409                     DEBUG_EVENT1("AFS DriveMap","Failed to read GlobalAutoMapper values: %d",dwResult);
1410                 }
1411                 break;
1412             }
1413         }
1414         dwResult=MountDOSDrive(*szDriveToMapTo,(const char *)szSubMount,FALSE,NULL);
1415     }
1416     RegCloseKey(hKey);
1417     return TRUE;
1418 }
1419
1420 DWORD MountDOSDrive(char chDrive,const char *szSubmount,BOOL bPersistent,const char * pUsername)
1421 {
1422     DWORD err;
1423         BOOL succ;
1424         TCHAR szPath[MAX_PATH], szTokens[MAX_PATH], *tok;
1425     TCHAR szClient[MAX_PATH];
1426     TCHAR szDrive[3] = TEXT("?:");
1427
1428 #ifdef AFSIFS
1429     int pathCount, currPos, lastPos, x;
1430     
1431     pathCount = 0;
1432
1433     pathCount = 0;
1434     strcpy(szTokens, szSubmount);
1435     tok = strtok(szTokens, "/\\");
1436     strcpy(szPath, "");
1437     while (tok)
1438     {
1439         if (pathCount || stricmp(tok, "afs"))
1440         {
1441             strcat(szPath, "\\");
1442             strcat(szPath, tok);
1443             pathCount++;
1444         }
1445         tok = strtok(NULL, "/\\");
1446     }
1447
1448     sprintf(szDrive,"%c:",chDrive);
1449     strcpy(szTokens, szPath);
1450     sprintf(szPath,"\\Device\\afsrdr\\%d%s",pathCount,szTokens);
1451     //succ = DefineDosDevice(DDD_RAW_TARGET_PATH, "J:", "\\Device\\afsrdr\\2\\ericjw\\test");
1452     succ = DefineDosDevice(DDD_RAW_TARGET_PATH, szDrive, szPath);
1453     err = GetLastError();
1454
1455     return succ ? NO_ERROR : ERROR_DEVICE_IN_USE;
1456 #else
1457     sprintf(szDrive,"%c:",chDrive);
1458     GetClientNetbiosName (szClient);
1459     sprintf(szPath,"\\\\%s\\%s",szClient,szSubmount);
1460     NETRESOURCE nr;
1461     memset (&nr, 0x00, sizeof(NETRESOURCE));
1462     nr.dwType=RESOURCETYPE_DISK;
1463     nr.lpLocalName=szDrive;
1464     nr.lpRemoteName=szPath;
1465     nr.dwDisplayType = RESOURCEDISPLAYTYPE_SHARE; /* ignored parameter */
1466     DWORD res=WNetAddConnection2(&nr,NULL,pUsername,(bPersistent)?CONNECT_UPDATE_PROFILE:0);
1467     DEBUG_EVENT5("AFS DriveMap","Mount %s Local[%s] Remote[%s] User[%s]=%x",
1468                   (bPersistent)?"Persistant" : "NonPresistant",
1469                   szDrive,szPath,pUsername?pUsername:"NULL",res);
1470     return res;
1471 #endif
1472 }
1473
1474 DWORD DisMountDOSDriveFull(const char *szPath,BOOL bForce)
1475 {
1476 #ifndef AFSIFS
1477     DWORD res=WNetCancelConnection(szPath,bForce);
1478 #else
1479     DWORD res;
1480     res = ERROR_DEVICE_IN_USE;
1481     // must handle drive letters and afs paths
1482     // DDD_REMOVE_DEFINITION
1483 #endif
1484     DEBUG_EVENT3("AFS DriveMap","%sDismount Remote[%s]=%x",
1485                   bForce ? "Forced " : "",szPath,res);
1486     return (res==ERROR_NOT_CONNECTED)?NO_ERROR:res;
1487 }
1488
1489 DWORD DisMountDOSDrive(const char *pSubmount,BOOL bForce)
1490 {
1491     TCHAR szPath[MAX_PATH];
1492     TCHAR szClient[MAX_PATH];
1493     GetClientNetbiosName (szClient);
1494     sprintf(szPath,"\\\\%s\\%s",szClient,pSubmount);
1495     return DisMountDOSDriveFull(szPath,bForce);
1496 }
1497
1498
1499 DWORD DisMountDOSDrive(const char chDrive,BOOL bForce)
1500 {
1501     TCHAR szPath[MAX_PATH];
1502     DWORD succ;
1503
1504     sprintf(szPath,"%c:",chDrive);
1505 #ifdef AFSIFS
1506     succ = DefineDosDevice(DDD_REMOVE_DEFINITION, szPath, NULL);
1507     return (!succ) ? GetLastError() : 0;
1508 #else
1509     return DisMountDOSDriveFull(szPath,bForce);
1510 #endif
1511 }