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