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