--- /dev/null
+
+Registry keys used in the Windows AFS Client
+--------------------------------------------
+
+This file describes the registry keys used in the Windows AFS clients.
+
+1. Service parameters
+---------------------
+
+The service parameters primarily affect the behavior of the AFS client
+service (afsd_service.exe).
+
+Regkey:
+[HKLM\SYSTEM\CurrentControlSet\Services\TransarcAFSDaemon\Parameters]
+
+Value : LANadapter
+Type : DWORD
+Default : -1
+Variable: LANadapter
+
+ LAN adapter number to use. This is the lana number of the LAN
+ adapter that the SMB server should bind to. If unspecified or set
+ to -1, a LAN adapter with named 'AFS' or a loopback adapter will be
+ selected. If neither are present, then all available adapters will
+ be bound to. When binding to a non-loopback adapter, the NetBIOS
+ name '%hostname%-AFS' will be used (where %hostname% is the NetBIOS
+ name of the host truncated to 11 characters). Otherwise, the NetBIOS
+ name will be 'AFS'.
+
+Value : CacheSize
+Type : QWORD
+Default : 20480 (CM_CONFIGDEFAULT_CACHESIZE)
+Variable: cm_initParams.cacheSize
+
+ Size of the AFS cache.
+
+Value : ChunkSize
+Type : DWORD
+Default : 15 (CM_CONFIGDEFAULT_CHUNKSIZE)
+Variable: cm_logChunkSize (cm_chunkSize = 1 << cm_logChunkSize)
+
+ Size of chunk for reading and writing. Actual chunk size is 2^cm_logChunkSize.
+
+Value : Daemons
+Type : DWORD
+Default : 2 (CM_CONFIGDEFAULT_DAEMONS)
+Variable: numBkgD
+
+ Number of background daemons (number of threads of
+ cm_BkgDaemon). (see cm_BkgDaemon in cm_daemon.c)
+
+Value : ServerThreads
+Type : DWORD
+Default : 4 (CM_CONFIGDEFAULT_SVTHREADS)
+Variable: numSvThreads
+
+ Number of SMB server threads (number of threads of smb_Server). (see
+ smb_Server in smb.c).
+
+Value : Stats
+Type : QWORD
+Default : 1000 (CM_CONFIGDEFAULT_STATS)
+Variable: cm_initParams.nStatCaches
+
+ Cache configuration.
+
+Value : LogoffTokenTransfer
+Type : DWORD {1,0}
+Default : 1
+Variable: smb_LogoffTokenTransfer
+
+ If enabled (set to 1), activates functionality where the user's
+ tokens are kept intact until smb_LogofTokenTransferTimeout seconds
+ elapse after user logs off. If roaming profiles are used and the
+ roaming profile takes a long time to be written back, this ensures
+ that the tokens remain valid until the profile save is complete.
+
+Value : LogoffTokenTransferTimeout
+Type : QWORD
+Default : 10
+Variable: smb_LogoffTokenTransferTimeout
+
+ See LogoffTokenTransfer above.
+
+Value : RootVolume
+Type : REG_SZ
+Default : "root.afs"
+Variable: cm_rootVolumeName
+
+ Root volume name.
+
+Value : Mountroot
+Type : REG_SZ
+Default : "/afs"
+Variable: cm_mountRoot
+
+ Name of root mount point. In symlinks, if a path starts with
+ cm_mountRoot, it is assumed that the path is absolute (as opposed to
+ relative) and is adjusted accordingly. Eg: if a path is specified as
+ /afs/athena.mit.edu/foo/bar/baz and cm_mountRoot is "/afs", then the
+ path is interpreted as \\afs\all\athena.mit.edu\foo\bar\baz. If a
+ path does not start with with cm_mountRoot, the path is assumed to
+ be relative and suffixed to the reference directory (i.e. directory
+ where the symlink exists)
+
+Value : CachePath
+Type : REG_SZ
+Default : "\AFSCache"
+Variable: cm_CachePath
+
+ Location of on-disk cache file.
+
+Value : TrapOnPanic
+Type : DWORD {1,0}
+Default : 0
+Variable: traceOnPanic
+
+ Issues a breakpoint in the event of a panic. (breakpoint: _asm int 3).
+
+Value : IsGateway
+Type : DWORD {1,0}
+Default : 0
+Variable: isGateway
+
+ Select whether or not this AFS client should act as a gateway. If
+ set and the NetBIOS name hostname-AFS is bound to a physical NIC,
+ other machines in the subnet can access AFS via SMB connections to
+ hostname-AFS .
+
+Value : ReportSessionStartups
+Type : DWORD {1,0}
+Default : 0
+Variable: reportSessionStartups
+
+ If enabled, all SMB sessions created are recorded in the Application
+ event log.
+
+Value : TraceBufferSize
+Type : QWORD
+Default : 5000 (CM_CONFIGDEFAULT_TRACEBUFSIZE)
+Variable: traceBufSize
+
+ Number of entries to keep in trace log.
+
+Value : SysName
+Type : REG_SZ
+Default : "i386_nt40"
+Variable: cm_sysName
+
+ Self explanatory.
+
+Value : SecurityLevel
+Type : DWORD {1,0}
+Default : 0
+Variable: cryptall
+
+ Enables encryption on RX calls.
+
+Value : UseDNS
+Type : DWORD {1,0}
+Default : 1
+Variable: cm_dnsEnabled
+
+ Enables resolving volservers using AFSDB DNS queries. (see
+ afsdb-freelance-notes)
+
+Value : FreelanceClient
+Type : DWORD {1,0}
+Default : 0
+Variable: cm_freelanceEnabled
+
+ Enables freelance client. (see afsdb-freelance-notes)
+
+Value : HideDotFiles
+Type : DWORD {1,0}
+Default : 1
+Variable: smb_hideDotFiles
+
+ Enables marking dotfiles with the hidden attribute. Dot files are
+ files whose name starts with a period (excluding "." and "..").
+
+Value : MaxMpxRequests
+Type : DWORD
+Default : 50
+Variable: smb_maxMpxRequests
+
+ Maximum number of multiplexed SMB requests that can be made.
+
+Value : MaxVCPerServer
+Type : DWORD
+Default : 100
+Variable: smb_maxVCPerServer
+
+ Maximum number of SMB virtual circuits.
+
+Value : Cell
+Type : REG_SZ
+Default : <none>
+Variable: rootCellName
+
+ Name of root cell (the cell from which root.afs should be mounted in
+ \\afs\all).
+
+Value : RxNoJumbo
+Type : DWORD {0,1}
+Default : 0
+Variable: rx_nojumbo
+
+ If enabled, does not send or indicate that we are able to send or
+ receive RX jumbograms.
+
+Value : RxMaxMTU
+Type : DWORD
+Default : -1
+Variable: rx_mtu
+
+ If set to anything other than -1, uses that value as the maximum MTU
+ supported by the RX interface.
+
+2. Network provider parameters
+------------------------------
+Affects the network provider (aklogon.dll).
+
+Regkey:
+[HKLM\SYSTEM\CurrentControlSet\Services\TransarcAFSDaemon\Parameters]
+
+Value : FailLoginsSilently
+Type : DWORD
+Default : 0
+
+Do not display message boxes if the login fails.
+
+Regkey:
+[HKLM\SYSTEM\CurrentControlSet\Services\TransarcAFSDaemon\NetworkProvider]
+
+Value : NoWarnings
+Type : DWORD
+Default : 0
+
+Disables visible warnings during logon.
+
$(NTMAKE)
$(CD) ..\..\..
-finale: client_creds
+extra: client_creds
+! IF EXIST($(SRC)\WINNT\extra) && EXIST($(SRC)\WINNT\extra\NTMakefile)
+ echo ***** $@
+ $(DOCD) $(SRC)\WINNT\$@
+ $(CD) $(SRC)\WINNT\$@
+ $(NTMAKE)
+ $(CD) ..\..\..
+! ELSE
+ echo ***** Skipping $@ ***** Not found.
+! ENDIF
+
+finale: extra
echo ***** $@
$(DOCD) $(SRC)\$@
$(CD) $(SRC)\$@
# InstallShield dependencies
-InstallShield5:
- echo ***** afs_setup_utils
- $(DOCD) $(SRC)\WINNT\afs_setup_utils
- $(CD) $(SRC)\WINNT\afs_setup_utils
- $(NTMAKE)
- $(CD) ..\..\..
-
- $(DOCD) $(SRC)\WINNT\install\$@
- $(CD) $(SRC)\WINNT\install\$@
- $(NTMAKE)
- $(CD) ..\..\..\..
-
-media: InstallShield5 NSIS
-
# Clean target for obj tree
clean:
nmake /nologo /f ntmakefile "NTMAKE = nmake /nologo /f ntmakefile clean" "NTMAKE_HEADERS = nmake /nologo /f ntmakefile clean" "NTMAKE_OBJS = nmake /nologo /f ntmakefile clean" install
NSIS:
echo ***** Making NSIS Installer
- $(DOCD) $(SRC)\WINNT\install\NSIS
- $(CD) $(SRC)\WINNT\install\NSIS
+ $(DOCD) $(SRC)\WINNT\install\$@
+ $(CD) $(SRC)\WINNT\install\$@
$(NTMAKE)
$(CD) ..\..\..\..
+#msi:
+# echo ***** Making MSI Installer
+# $(DOCD) $(SRC)\WINNT\install\$@
+# $(CD) $(SRC)\WINNT\install\$@
+# $(NTMAKE)
+# $(CD) ..\..\..\..
+
+InstallShield5:
+ echo ***** afs_setup_utils
+ $(DOCD) $(SRC)\WINNT\afs_setup_utils
+ $(CD) $(SRC)\WINNT\afs_setup_utils
+ $(NTMAKE)
+ $(CD) ..\..\..
+
+ $(DOCD) $(SRC)\WINNT\install\$@
+ $(CD) $(SRC)\WINNT\install\$@
+ $(NTMAKE)
+ $(CD) ..\..\..\..
+
+media: install InstallShield5 NSIS
+
install-nsis: install NSIS
+install-msi: install msi
+
install-is5: install InstallShield5
-This software has been released under the terms of the IBM Public\r
-License. For details, see the LICENSE file in the top-level source\r
-directory or on-line at http://www.openafs.org/dl/license10.html\r
-\r
-The document now provides a step by step procedure that takes the user \r
-from a basic Windows NT/2000 workstation to an OpenAFS development \r
-environment. Details are provided so that a 'beginning' windows \r
-developer can build an OpenAFS installable package for Windows NT/2000. \r
-\r
-*********** Windows NT/2000 Build Process ****************\r
-\r
-Building OpenAFS for Windows requires configuring a Windows\r
-development system by installing compilation tools and header files.\r
-Open AFS Software development can be done on Windows NT or 2000. The\r
-target system, where OpenAFS will be installed, should be either\r
-Windows NT or Windows 2000. The building process is controlled by a\r
-nmake file that generates the necessary binaries and binds them into an\r
-install package.\r
-\r
-The following steps describe how to configure Windows 2000/NT:\r
-\r
- A. Obtain a copy of the OpenAFS Source Tree\r
- B. Install Compiler and Development tools.\r
- C. Set up drive mappings.\r
- D. Install SDK header files\r
- E. Configure Environment variables\r
- F. Set program version Level\r
- G. Build Win2000 binaries\r
- H. Install InstallShield 5.x\r
- I. Build Win2000 InstallShield Package\r
- J. Build Win2000 InstallShield Package for the Web\r
- K. Final Results\r
- L. Creating a Debug Environment\r
- M. Optional Items\r
- N. Required patches for 1.2.2a and earlier releases\r
- \r
-The Software development tools with InstallShield require 900 MB\r
-storage.\r
-\r
-The Software development tools (without InstallShield) require 660 MB\r
-storage.\r
-\r
-The OpenAFS Source directory requires about 200 MB storage. The Source\r
-directory size includes additional space for files that will be\r
-generated during the build process.\r
-\r
-The following CDs are used in this example:\r
- Microsoft SDK and Tools Jan 2001\r
- Microsoft Visual Studio Version 6.0\r
- InstallShield 5.5\r
-\r
-Different versions of above CDs can be used; however, building an\r
-install package for Windows NT/2000 requires InstallShield\r
-version 5.0 to 5.5 (version 6.0 or better will not work). \r
-\r
-You can build all the necessary binaries without the InstallShield\r
-software. InstallShield is only needed to build an install package.\r
-\r
-STEP A. Obtain a copy of the Open AFS Source Tree.\r
-\r
-Transfer OpenAFS source tree onto your hardrive. The source can be\r
-downloaded from the OpenAFS web site:\r
- http://www.OpenAFS.org/release/snapindex.html.\r
-\r
-For this example, download source for version 1.2.2a using the\r
-following URL:\r
-http://www.openafs.org/dl/openafs/1.2.2a/openafs-1.2.2a-src.tar\r
-\r
-HINT: DailySnapShots are pre-release source trees and much more\r
-likely to have compilation errors. If this is your first attempt, do\r
-your build based on a release version of the source, e.g. 1.2.2.a. Once\r
-you have completed a build process successfully, you can experiment with\r
-other source trees.\r
-\r
-You will need an unzip utility that can expand compressed tar files.\r
-For example "Pkzip for Windows" from Pkware will uncompress tar files.\r
-(http://www.pkware.com/)\r
-\r
-Expand the downloaded tar file (openafs-1.2.2a-src.tar) into target\r
-directory (c:\OpenAFS), the unzip routine will expand the source into a\r
-subdirectory tree:\r
- c:\OpenAFS\OpenAFS-1.2.2a\src\r
-\r
-Copy files NTMAKEFILE from 'src' to the AFS base directory:\r
-\r
-From a DOS command prompt window, enter the following copy commands:\r
-\r
-copy c:\OpenAFS\OpenAFS-1.2.2a\src\NTMAKEFILE c:\OpenAFS\OpenAFS-1.2.2a\.\r
-\r
-The AFS base directory should look something like the following:\r
-\r
-c:\OpenAFS\OpenAFS-1.2.2a\\r
- NTMakefile\r
- src\r
- \r
-STEP B. Install compiler and development tools.\r
-\r
-Install a copy of Microsoft Visual C++ 5.0 or 6.0. The "Typical" install\r
-setting is sufficient.\r
-\r
-(1) You can reduce the installation size by selecting "Custom" install\r
-and remove all but the following Options:\r
-\r
- Microsoft Visual C++\r
- Data Access\r
-\r
-(2) When asked, Select to Register Environment Variables.\r
-\r
-(3) After rebooting you have to choice to install additional software\r
-packages. It is not necessary to install these packages.\r
-\r
-STEP C. Map development drive letters.\r
-\r
-The following documentation will assume you are mapping the Y: drive to\r
-the OpenAFS source directory and you are mapping X: drive to your\r
-development tools directory. Other configurations will work, including\r
-not mapping any drives, as long as the path assignments are consistent\r
-and you don't exceed the maximum environment variable length.\r
-\r
-Y: drive mapping provides a consistent directory location to build from.\r
-Building OpenAFS will require you to open up a command DOS prompt,\r
-navigate to drive Y: and execute the nmake file. The source is based\r
-from Y: drive and the generated files are based from Y:\DEST. If the OpenAFS \r
-source tree is at a different location, you only need to re-map the\r
-Y: drive.\r
-\r
-X: drive mapping shortens the length of several Environment variables\r
-by mapping it to a directory where Visual Studio is installed. Although\r
-this step is not important when using Windows NT or 2000 as a\r
-development OS, it does reduce the chance of typing errors during\r
-the configuration phase.\r
-\r
-From a DOS command window enter the following commands:\r
-\r
-SUBST y: c:\OpenAFS\OpenAFS-1.2.2a\r
-SUBST x: "c:\Program Files\Microsoft Visual Studio\VC98"\r
-\r
-SUBST is persistent across DOS command prompts; that is, if you open up\r
-another DOS command prompt the mapped drives are still defined.\r
-However, if you reboot the mapped drives using SUBST will be lost. \r
-\r
-If you need to remove Y: drive mapping, execute the following command\r
-from a DOS command prompt window:\r
-\r
-SUBST y: /d\r
-\r
-STEP D. Install SDK header files.\r
-\r
-Files from Microsoft's Platform SDK for NT or 98 are required to\r
-complete a build on NT/2000.\r
-\r
-The header files that are required are found from a Microsoft SDK are:\r
-\r
- netspi.h\r
- npapi.h\r
-\r
-These files come from Microsoft DDKs/SDKs as follows:\r
-\r
- January 1997 Windows NT Workstation DDK - /ddk/frc/network/inc/npapi.h\r
- November 2001 Microsoft Platform SDK - install "samples" from "Core SDK"\r
- samples/winbase/security/winnt/logonnp/npapi.h\r
- July 1998 Windows 95 DDK - net/inc/netmpr.h and net/inc/netspi.h\r
- July 1999 Windows 98 DDK - src/net/inc/netmpr.h and src/net/inc/netspi.h\r
- - you need to install "Legacy and Related\r
- driver samples"\r
-\r
-To Install Platform SDK from CDROM\r
- \r
- Run "setup.exe default.htm" from CDROM:\r
- Select Microsoft Core SDK\r
- Select Sample and Source\r
- Select installation path x:\SDK\r
-\r
-To Install Windows SDK from WEB:\r
- http://www.microsoft.com/sdk\r
-\r
-STEP E. Configure the OpenAFS build environment.\r
-\r
-The following environment variables should be set:\r
-\r
-SET AFSDEV_LIB=%LIB%\r
-SET AFSROOT=Y:\r
-SET SYS_NAME=i386_nt40\r
-SET _WIN32_IE=0x400\r
-SET MSSDK=X:\Sdk\r
-SET MSTOOLS=X:\Sdk\r
-SET MSVCDIR=X:\r
-SET AFSDEV_BIN=X:\BIN\r
-SET AFSDEV_BUILDTYPE=FREE\r
-SET AFSDEV_INCLUDE=X:\Sdk\samples\winbase\security\winnt\logonNP;X:\Sdk\Include\ATL30;X:\Sdk\Include;%INCLUDE%\r
-\r
-Please do not include unnecessary spaces in AFSDEV_INLCUDE.\r
-\r
-Create a batch file (SETAFS.BAT) to make these settings that can be \r
-executed when you bring up a DOS command prompt window. Environment \r
-variables are not persistent, if you close the DOS command window \r
-or reboot, the environment variables are lost and they must be \r
-recreated when you open a new DOS command prompt window.\r
-\r
-HINT: SET AFSDEV_BUILDTYPE=CHECKED if you want debug information\r
-included in your binaries.\r
-\r
-HINT: Adding drive mapping commands to the batch file makes it easy to\r
-establish your development environment even if you logoff. I suggest\r
-adding the following lines to the beginning of the batch file:\r
-\r
-SUBST y: /d\r
-SUBST x: /d\r
-SUBST y: c:\OpenAfs\OpenAFS-1.2.2a\r
-SUBST x: "c:\Program Files\Microsoft Visual Studio\VC98"\r
-\r
-HINT: Windows 2000/NT provides an alternate way to set environment\r
-variables in System Proprieties. These can be accessed from the system\r
-control panel, advanced tab, Environment Variables. These are\r
-persistent and will be reset every time a DOS command prompt window is\r
-opened.\r
-\r
-STEP F. Set version and installation options\r
-\r
-Add a CellServDB file to install area. CellServDB contains the entries\r
-for the various cell names. You can download a general purpose one\r
-from:\r
- http://grand.central.org/dl/cellservdb/CellServDB\r
-then copy it to Y:\DEST\Wininstall\Config\CellServDB.GrandCentral\r
-\r
-Note: Create directory Y:\DEST\Wininstall\Config\ if it doesn't exist.\r
-\r
-Edit file Y:\src\config\NTMakefile.i386_nt40\r
- AFSPRODUCT_VERSION - Product version\r
- CELLSERVDB_INSTALL - The default file name for the CellServDB\r
- included in the install Package.\r
- CELLNAME_DEFAULT - The default home cell name.\r
- CELLSERVDB_WEB - The default web address to obtain CellServDB\r
-\r
-For example: in the file Y:\src\config\NTMakefile.i386_nt40 you would\r
-see the following:\r
-\r
- AFSPRODUCT_VERSION=1.2.2a\r
- CELLNAME_DEFAULT=home.cell.com\r
- CELLSERVDB_INSTALL=CellServDB.GrandCentral\r
- CELLSERVDB_WEB=http://grand.central.org/dl/cellservdb/CellServDB\r
-\r
-During the Open AFS installation process the user will be presented\r
-with two choices for the CellServDB: Local copy (CELLSERVDB_INSTALL) and\r
-one that can be downloaded from the web (CELLSERVDB_WEB).\r
-\r
-HINT: The product version number (AFSPRODUCT_VERSION) can be changed to\r
-create a new version number. For example if you have added source\r
-changes to OpenAFS-1.2.2a and you wanted to create a new version level,\r
-you may want to use the following: AFSPRODUCT_VERSION=1.2.2b\r
-\r
-STEP G. Begin the build\r
-\r
-(1) From Windows 2000 open up a DOS prompt window.\r
-\r
-(2) Clean the work area.\r
-\r
- nmake /f NTMakefile clean\r
-\r
-(3) Build the complete Windows NT/2000 development environment.\r
-\r
- nmake /f NTMakefile install\r
-\r
-While the build is running you will see many compile warnings. This\r
-behavior is normal; the build process is successful as long as the build\r
-process doesn't terminate with an error ("nmake.exe return code 0x2")\r
-and it displays 'Build Finished Successfully'.\r
-\r
-STEP H. Install InstallShield (optional).\r
-\r
-In order to build an install package for OpenAFS, InstallShield 5.5\r
-must be installed along with InstallShield East and West\r
-multi-Language packs.\r
-\r
-(1) Install InstallShield (version between 5.0 and 5.5)\r
-\r
-For minimum installation choose "compact".\r
-\r
-(2) Install West Language Pack (5.5)\r
-\r
-(3) Install East Language Pack (5.5)\r
-\r
-NOTE: InstallShield's versions 6 and higher WILL NOT WORK for\r
-Windows NT/2000 build process.\r
-\r
-(4) Add necessary DLL's to work with the InstallShield package.\r
-\r
-Two Microsoft DLL's are missing from the InstallShield package. These\r
-DLL's must be copied to Y:\DEST\WinInstall\Config\:\r
- SHLWAPI.DLL \r
- WININET.DLL\r
-\r
-These files are only used during the installation, and they will not \r
-be left on the target machine. They can be located at \r
-%SystemRoot%\SYSTEM32.\r
-\r
-From a DOS command prompt window enter the following commands:\r
-\r
-copy %systemRoot%\System32\SHLWAPI.DLL y:\dest\wininstall\config\.\r
-copy %systemRoot%\System32\WININET.DLL y:\dest\wininstall\config\.\r
-\r
-(5) Add two Environment variables to the bottom of the batch file,\r
-SETAFS.BAT (see STEP E:).\r
-\r
-SET IS5ROOT="C:\Program Files\InstallShield\InstallShield 5.5 Professional Edition"\r
-SET AFSDEV_INCLUDE=%AFSDEV_INCLUDE%;%IS5ROOT%\Include\r
-\r
-STEP I. Build Win2000 InstallShield package\r
-\r
-From the DOS command prompt window run:\r
-\r
- Y:\r
- nmake /f NTMakefile media\r
-\r
-While the build is running you will see a few compile warnings. This\r
-behavior is normal; the build process is successful as long as the build\r
-process doesn't terminate with an error ("nmake.exe return code 0x2")\r
-and it displays 'Install Script Finished Successfully'.\r
-\r
-STEP J. Build Win2000 InstallShield package for the Web\r
-\r
-InstallShield's PackageForTheWeb combines the installation files into a\r
-single application file that will expand on execution and lead you\r
-through the OpenAFS installation. \r
-\r
-Install PackageForTheWeb 3 from InstallShield\r
-\r
-Add Environment variables to the bottom of the batch file, SETAFS.BAT\r
-(see STEP E:).\r
-\r
-SET ISWEB="C:\Program Files\InstallShield\PackageForTheWeb 3"\r
-\r
-From the DOS command prompt window run:\r
-\r
- Y:\r
- nmake /f NTMakefile media\r
-\r
-While the build is running you will see a few compile warnings. This\r
-behavior is normal; the build process is successful as long as the build\r
-process doesn't terminate with an error ("nmake.exe return code 0x2") and\r
-it displays 'Install Script Finished Successfully'.\r
-\r
-HINT: It is only necessary to run "nmake /f NTMakefile media" once, by \r
-combining steps I & J. \r
-\r
-STEP K. Final Results\r
-\r
-The build process generates its binaries in Y:\DEST. The subdirectory\r
-would look like the following:\r
-\r
-Y:\DEST\r
- bin\r
- etc\r
- include\r
- lib\r
- root.client\r
- root.server\r
- WinInstall\r
-\r
-Y:\DEST\Bin - contains build utilities.\r
-Y:\DEST\root.client - contains Open AFS binaries\r
-Y:\DEST\root.server - contain Open AFS Server binaries\r
-Y:\DEST\WinInstall\PackageWeb\AFSforWindows.exe - is the Web install\r
-package for Open AFS.\r
-Y:\DEST\WinInstall\ - are the install package files for Open AFS\r
-\r
-Step L. Creating a Debug Environment\r
-\r
-Instructions on building a debugging environment from Visual Studio C++\r
-workspace. This example give the user a way to step through the source\r
-code for AFSCREDS.EXE.\r
-\r
-These instructions are to be followed after you have set up the\r
-development environment.\r
-\r
-The following steps must be done before you can build a debug\r
-environment:\r
-\r
-1. Set up the development environment as described above\r
-2. set AFS_BUILDTYPE=CHECKED to get debug information.\r
-3. You must use environment variables in System Properties\r
-4. Do a complete build.\r
-\r
-To set the the environment variables in the System Properties:\r
-1. Select the 'System' icon in the control Panel\r
-2. Select the 'Advanced' tab\r
-3. Select the 'Environment Variables' button\r
-4. In the user area set all variables as you did above that\r
-were used in the setafs.bat file.\r
-\r
-To build a new work space to debug afs_creds.exe:\r
-\r
-1. Create New Workspace - \r
-Select from Microsoft Visual C++ toolbar file New\r
-Select from 'new' Project Tab Makefile Project name: Creds\r
-Location Y:\src\winnt\client_creds\r
-Select OK\r
-\r
-From Dialog Box 'Makefile - Step 1 of 2'\r
-command line= nmake /f"ntmakefile" install\r
-Output = y:\dest\root.client\usr\vice\etc\AFSCREDS.EXE\r
-Select NEXT\r
-\r
-Dialog Box 'Makefile - Step 2 of 2'\r
-Command line= nmake /f"ntmakefile" install\r
-Output = y:\dest\root.client\usr\vice\etc\AFSCREDS.EXE\r
-\r
-Select Finish\r
-\r
-Switch to FileView\r
-Right click on 'Source Files' and select 'Add Files to folder', select\r
-all *.cpp files.\r
-\r
-Right click on 'Header Files' and select 'Add Files to folder', select\r
-all *.h files.\r
-\r
-Right click on 'creds files' and select 'New Folder'\r
-Fill name in 'Build'\r
-\r
-From the toolbar select Build\r
-Select 'Build All'\r
-\r
-You should see the following string when the compile is finished:\r
-"afs_creds.exe - 0 errors(0), 0 warnings(s)"\r
-\r
-Press <F5> to execute afs_creds.exe.\r
-\r
-STEP M. Optional Items\r
-\r
-The build process has an error table that is compiled for many OpenAFS\r
-applications. This table is generated by Unix based tools. It is not\r
-normally necessary to modify this table so pre-generated source files\r
-are included in the OpenAFS source. If you need to make modifications\r
-in these areas the Unix base tools that run on Windows can be found on\r
-the web. For example:\r
-\r
- http://cygwin.com/\r
-\r
-Below is a short explanation how to update the error table.\r
-\r
-(1) Install flex and bison from a Unix based tool provider.\r
-\r
-(2) Make changes to the source files.\r
-\r
-There are two files in the source tree that are processed with lex\r
-and yacc on UNIX systems, src/comerr/et_lex.lex.l and\r
-src/comerr/error_table.y, that when processed produce the files\r
-et_lex.lex_nt.c, error_table_nt.c, and error_table_nt.h.\r
-\r
-Since NT does not include lex and yacc or any equivalent tools, we\r
-have provided the output files that lex and yacc produce (using Win32\r
-ports of flex and bison). This will allow builds to work for anyone\r
-who does not need to change the .l and .y files.\r
-\r
-If you do need to change et_lex.lex.l, then you will need to install\r
-Win32 port of flex on your system. Put flex.exe in a directory on the\r
-path and rebuild.\r
-\r
-If you do need to change error_table.y, then you will need to install\r
-a Win32 port of bison on your system. Put bison.exe in a directory on\r
-the path, configure bison as explained in step 5, and rebuild.\r
-\r
-You can also attempt to use other replacements for lex and yacc. This\r
-will require modifying the LEX and YACC settings in\r
-/config/NTMakefile.i386_nt40. If the replacements require different\r
-command line options than flex and bison, then you may also need to\r
-change src/comerr/NTMakefile.\r
-\r
-(3) Generate new OpenAFS binaries\r
-\r
-\r
-STEP N. Required patches for 1.2.2a and earlier releases\r
-\r
-There are two set of patches must be applied to 1.2.2a source to\r
-successfully build the binaries:\r
-\r
-(1) Patches applied to 1.2.2a to build binaries, excluding install\r
-package.\r
-\r
-diff -Nur --exclude-from=exclude bas/src/NTMakefile upd/src/NTMakefile\r
---- bas/src/NTMakefile Wed Nov 14 19:38:06 2001\r
-+++ upd/src/NTMakefile Mon Dec 3 14:41:12 2001\r
-@@ -471,6 +471,7 @@\r
- $(CD) $(OBJ)\$@\r
- $(NTMAKE)\r
- $(CD) ..\.. \r
-+ echo Build Finished Successfully\r
- \r
- install: start finale\r
- \r
-@@ -487,6 +488,7 @@\r
- $(CD) ..\..\..\..\r
- \r
- media: InstallShield5\r
-+ echo Install Script Finished Successfully\r
- \r
- \r
-(2) Patches applied to 1.2.2a to build install package.\r
-\r
-diff -Nur --exclude-from=exclude bas/src/WINNT/afsd/NTMakefile upd/src/WINNT/afsd/NTMakefile\r
---- bas/src/WINNT/afsd/NTMakefile Tue Nov 20 22:45:40 2001\r
-+++ upd/src/WINNT/afsd/NTMakefile Wed Dec 5 11:42:46 2001\r
-@@ -169,8 +169,8 @@\r
- $(EXEDIR)\tokens.exe \\r
- $(EXEDIR)\unlog.exe $(EXEDIR)\afsd.exe $(EXEDIR)\afsd_service.exe \\r
- $(EXEDIR)\fs.exe $(EXEDIR)\symlink.exe \\r
-- $(LOGON_DLLFILE) $(LOG95_DLLFILE) \\r
-- $(EXEDIR)\afsshare.exe \\r
-+ $(LOGON_DLLFILE) \\r
-+ $(EXEDIR)\afsshare.exe \\r
- $(DESTDIR)\bin\kpasswd.exe\r
- \r
- install9X: install_headers $(CONF_DLLFILE) \\r
-\r
-diff -Nur --exclude-from=exclude bas/src/WINNT/install/InstallShield5/NTMakefile upd/src/WINNT/install/InstallShield5/NTMakefile\r
---- bas/src/WINNT/install/InstallShield5/NTMakefile Wed Nov 14 19:38:50 2001\r
-+++ upd/src/WINNT/install/InstallShield5/NTMakefile Mon Dec 3 16:43:08 2001\r
-@@ -60,7 +60,7 @@\r
- $(MKDIR) $(DESTDIR)\Wininstall\PackageWeb\r
- ! ENDIF\r
- $(DEL) /q $(DESTDIR)\Wininstall\PackageWeb\*.*\r
-- $(ISWEB)\Pftwwiz.exe $(AFSROOT)\src\winnt\install\InstallShield5\PackageWeb.pfw -s -a \r
-+ "$(ISWEB)\Pftwwiz.exe" $(AFSROOT)\src\winnt\install\InstallShield5\PackageWeb.pfw -s -a \r
- !ENDIF\r
- xcopy /s/e/y "Media\OpenAFS\Disk Images\disk1\*.*" $(DESTDIR)\WinInstall\r
- copy AFS_component_version_number.txt $(DESTDIR)\WinInstall\Version.txt\r
-diff -Nur --exclude-from=exclude bas/src/WINNT/afs_setup_utils/_isuser/_IsUser.RC upd/src/WINNT/afs_setup_utils/_isuser/_IsUser.RC\r
---- bas/src/WINNT/afs_setup_utils/_isuser/_IsUser.RC Thu Sep 6 20:54:58 2001\r
-+++ upd/src/WINNT/afs_setup_utils/_isuser/_IsUser.RC Mon Dec 3 15:11:46 2001\r
-@@ -10,7 +10,7 @@\r
- #define APSTUDIO_HIDDEN_SYMBOLS\r
- #include "windows.h"\r
- #undef APSTUDIO_HIDDEN_SYMBOLS\r
--#include <.\sdrc.h>\r
-+#include <sdrc.h>\r
- \r
- /////////////////////////////////////////////////////////////////////////////\r
- #undef APSTUDIO_READONLY_SYMBOLS\r
-diff -Nur --exclude-from=exclude bas/src/WINNT/afs_setup_utils/_isuser/_IsUser.dep upd/src/WINNT/afs_setup_utils/_isuser/_IsUser.dep\r
---- bas/src/WINNT/afs_setup_utils/_isuser/_IsUser.dep Thu Sep 6 20:54:58 2001\r
-+++ upd/src/WINNT/afs_setup_utils/_isuser/_IsUser.dep Wed Dec 31 16:00:00 1969\r
-@@ -1,5 +0,0 @@\r
--# Microsoft Developer Studio Generated Dependency File, included by _IsUser.mak\r
--\r
--.\_Isuser.RC : \\r
-- ".\sdrc.h"\\r
-- \r
-diff -Nur --exclude-from=exclude bas/src/WINNT/afs_setup_utils/_isuser/ntmakefile upd/src/WINNT/afs_setup_utils/_isuser/ntmakefile\r
---- bas/src/WINNT/afs_setup_utils/_isuser/ntmakefile Mon Sep 10 09:39:50 2001\r
-+++ upd/src/WINNT/afs_setup_utils/_isuser/ntmakefile Mon Dec 3 15:16:04 2001\r
-@@ -30,14 +30,6 @@\r
- "$(OUTDIR)" ::\r
- if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"\r
- \r
--HEADERS = ".\sdrc.h"\r
--\r
--".\sdrc.h" : $(IS5ROOT)\INCLUDE\sdrc.h\r
-- $(COPY) $(IS5ROOT)\INCLUDE\sdrc.h .\r
--! IF EXIST($(IS5ROOT)\Script\ISRT\Include\sdrc.h)\r
-- $(COPY) $(IS5ROOT)\Script\ISRT\Include\sdrc.h .\r
--! ENDIF\r
--\r
- CPP=cl.exe\r
- CPP_PROJ=/nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "_ISUSER_EXPORTS" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c \r
- \r
-@@ -85,20 +77,10 @@\r
- "$(INTDIR)\_isuser.obj" \\r
- "$(INTDIR)\_Isuser.res"\r
- \r
--"$(OUTDIR)\_IsUser.dll" : "$(OUTDIR)" $(HEADERS) $(DEF_FILE) $(LINK32_OBJS)\r
-+"$(OUTDIR)\_IsUser.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)\r
- $(LINK32) @<<\r
- $(LINK32_FLAGS) $(LINK32_OBJS)\r
- <<\r
--\r
--\r
--!IF "$(NO_EXTERNAL_DEPS)" != "1"\r
--!IF EXISTS("_IsUser.dep")\r
--!INCLUDE "_IsUser.dep"\r
--!ELSE \r
--!MESSAGE Warning: cannot find "_IsUser.dep"\r
--!ENDIF \r
--!ENDIF \r
--\r
- \r
- SOURCE=.\_isuser.c\r
+This software has been released under the terms of the IBM Public
+License. For details, see the LICENSE file in the top-level source
+directory or on-line at http://www.openafs.org/dl/license10.html
+
+The document now provides a step by step procedure that takes the user
+from a basic Windows NT/2000 workstation to an OpenAFS development
+environment. Details are provided so that a 'beginning' windows
+developer can build an OpenAFS installable package for Windows NT/2000.
+
+*********** Windows NT/2000 Build Process ****************
+
+Building OpenAFS for Windows requires configuring a Windows
+development system by installing compilation tools and header files.
+Open AFS Software development can be done on Windows NT or 2000. The
+target system, where OpenAFS will be installed, should be either
+Windows NT or Windows 2000. The building process is controlled by a
+nmake file that generates the necessary binaries and binds them into an
+install package.
+
+The following steps describe how to configure Windows 2000/NT:
+
+ A. Obtain a copy of the OpenAFS Source Tree
+ B. Install Compiler and Development tools.
+ C. Set up drive mappings.
+ D. Install SDK header files
+ E. Configure Environment variables
+ F. Set program version Level
+ G. Build Win2000 binaries
+ H. Install InstallShield 5.x
+ I. Build Win2000 InstallShield Package
+ J. Build Win2000 InstallShield Package for the Web
+ K. Final Results
+ L. Creating a Debug Environment
+ M. Optional Items
+ N. Required patches for 1.2.2a and earlier releases
+
+The Software development tools with InstallShield require 900 MB
+storage.
+
+The Software development tools (without InstallShield) require 660 MB
+storage.
+
+The OpenAFS Source directory requires about 200 MB storage. The Source
+directory size includes additional space for files that will be
+generated during the build process.
+
+The following CDs are used in this example:
+ Microsoft SDK and Tools Jan 2001
+ Microsoft Visual Studio Version 6.0
+ InstallShield 5.5
+
+Different versions of above CDs can be used; however, building an
+install package for Windows NT/2000 requires InstallShield
+version 5.0 to 5.5 (version 6.0 or better will not work).
+
+You can build all the necessary binaries without the InstallShield
+software. InstallShield is only needed to build an install package.
+
+STEP A. Obtain a copy of the Open AFS Source Tree.
+
+Transfer OpenAFS source tree onto your hardrive. The source can be
+downloaded from the OpenAFS web site:
+ http://www.OpenAFS.org/release/snapindex.html.
+
+For this example, download source for version 1.2.2a using the
+following URL:
+http://www.openafs.org/dl/openafs/1.2.2a/openafs-1.2.2a-src.tar
+
+HINT: DailySnapShots are pre-release source trees and much more
+likely to have compilation errors. If this is your first attempt, do
+your build based on a release version of the source, e.g. 1.2.2.a. Once
+you have completed a build process successfully, you can experiment with
+other source trees.
+
+You will need an unzip utility that can expand compressed tar files.
+For example "Pkzip for Windows" from Pkware will uncompress tar files.
+(http://www.pkware.com/)
+
+Expand the downloaded tar file (openafs-1.2.2a-src.tar) into target
+directory (c:\OpenAFS), the unzip routine will expand the source into a
+subdirectory tree:
+ c:\OpenAFS\OpenAFS-1.2.2a\src
+
+Copy files NTMAKEFILE from 'src' to the AFS base directory:
+
+From a DOS command prompt window, enter the following copy commands:
+
+copy c:\OpenAFS\OpenAFS-1.2.2a\src\NTMAKEFILE c:\OpenAFS\OpenAFS-1.2.2a\.
+
+The AFS base directory should look something like the following:
+
+c:\OpenAFS\OpenAFS-1.2.2a\
+ NTMakefile
+ src
+
+STEP B. Install compiler and development tools.
+
+Install a copy of Microsoft Visual C++ 5.0 or 6.0. The "Typical" install
+setting is sufficient.
+
+(1) You can reduce the installation size by selecting "Custom" install
+and remove all but the following Options:
+
+ Microsoft Visual C++
+ Data Access
+
+(2) When asked, Select to Register Environment Variables.
+
+(3) After rebooting you have to choice to install additional software
+packages. It is not necessary to install these packages.
+
+STEP C. Map development drive letters.
+
+The following documentation will assume you are mapping the Y: drive to
+the OpenAFS source directory and you are mapping X: drive to your
+development tools directory. Other configurations will work, including
+not mapping any drives, as long as the path assignments are consistent
+and you don't exceed the maximum environment variable length.
+
+Y: drive mapping provides a consistent directory location to build from.
+Building OpenAFS will require you to open up a command DOS prompt,
+navigate to drive Y: and execute the nmake file. The source is based
+from Y: drive and the generated files are based from Y:\DEST. If the OpenAFS
+source tree is at a different location, you only need to re-map the
+Y: drive.
+
+X: drive mapping shortens the length of several Environment variables
+by mapping it to a directory where Visual Studio is installed. Although
+this step is not important when using Windows NT or 2000 as a
+development OS, it does reduce the chance of typing errors during
+the configuration phase.
+
+From a DOS command window enter the following commands:
+
+SUBST y: c:\OpenAFS\OpenAFS-1.2.2a
+SUBST x: "c:\Program Files\Microsoft Visual Studio\VC98"
+
+SUBST is persistent across DOS command prompts; that is, if you open up
+another DOS command prompt the mapped drives are still defined.
+However, if you reboot the mapped drives using SUBST will be lost.
+
+If you need to remove Y: drive mapping, execute the following command
+from a DOS command prompt window:
+
+SUBST y: /d
+
+STEP D. Install SDK header files.
+
+Files from Microsoft's Platform SDK for NT or 98 are required to
+complete a build on NT/2000.
+
+The header files that are required are found from a Microsoft SDK are:
+
+ netspi.h
+ npapi.h
+
+These files come from Microsoft DDKs/SDKs as follows:
+
+ January 1997 Windows NT Workstation DDK - /ddk/frc/network/inc/npapi.h
+ November 2001 Microsoft Platform SDK - install "samples" from "Core SDK"
+ samples/winbase/security/winnt/logonnp/npapi.h
+ July 1998 Windows 95 DDK - net/inc/netmpr.h and net/inc/netspi.h
+ July 1999 Windows 98 DDK - src/net/inc/netmpr.h and src/net/inc/netspi.h
+ - you need to install "Legacy and Related
+ driver samples"
+
+To Install Platform SDK from CDROM
+
+ Run "setup.exe default.htm" from CDROM:
+ Select Microsoft Core SDK
+ Select Sample and Source
+ Select installation path x:\SDK
+
+To Install Windows SDK from WEB:
+ http://www.microsoft.com/sdk
+
+STEP E. Configure the OpenAFS build environment.
+
+The following environment variables should be set:
+
+SET AFSDEV_LIB=%LIB%
+SET AFSROOT=Y:
+SET SYS_NAME=i386_nt40
+SET _WIN32_IE=0x400
+SET MSSDK=X:\Sdk
+SET MSTOOLS=X:\Sdk
+SET MSVCDIR=X:
+SET AFSDEV_BIN=X:\BIN
+SET AFSDEV_BUILDTYPE=FREE
+SET AFSDEV_INCLUDE=X:\Sdk\samples\winbase\security\winnt\logonNP;X:\Sdk\Include\ATL30;X:\Sdk\Include;%INCLUDE%
+
+Please do not include unnecessary spaces in AFSDEV_INLCUDE.
+
+Create a batch file (SETAFS.BAT) to make these settings that can be
+executed when you bring up a DOS command prompt window. Environment
+variables are not persistent, if you close the DOS command window
+or reboot, the environment variables are lost and they must be
+recreated when you open a new DOS command prompt window.
+
+HINT: SET AFSDEV_BUILDTYPE=CHECKED if you want debug information
+included in your binaries.
+
+HINT: Adding drive mapping commands to the batch file makes it easy to
+establish your development environment even if you logoff. I suggest
+adding the following lines to the beginning of the batch file:
+
+SUBST y: /d
+SUBST x: /d
+SUBST y: c:\OpenAfs\OpenAFS-1.2.2a
+SUBST x: "c:\Program Files\Microsoft Visual Studio\VC98"
+
+HINT: Windows 2000/NT provides an alternate way to set environment
+variables in System Proprieties. These can be accessed from the system
+control panel, advanced tab, Environment Variables. These are
+persistent and will be reset every time a DOS command prompt window is
+opened.
+
+STEP F. Set version and installation options
+
+Add a CellServDB file to install area. CellServDB contains the entries
+for the various cell names. You can download a general purpose one
+from:
+ http://grand.central.org/dl/cellservdb/CellServDB
+then copy it to Y:\DEST\Wininstall\Config\CellServDB.GrandCentral
+
+Note: Create directory Y:\DEST\Wininstall\Config\ if it doesn't exist.
+
+Edit file Y:\src\config\NTMakefile.i386_nt40
+ AFSPRODUCT_VERSION - Product version
+ CELLSERVDB_INSTALL - The default file name for the CellServDB
+ included in the install Package.
+ CELLNAME_DEFAULT - The default home cell name.
+ CELLSERVDB_WEB - The default web address to obtain CellServDB
+
+For example: in the file Y:\src\config\NTMakefile.i386_nt40 you would
+see the following:
+
+ AFSPRODUCT_VERSION=1.2.2a
+ CELLNAME_DEFAULT=home.cell.com
+ CELLSERVDB_INSTALL=CellServDB.GrandCentral
+ CELLSERVDB_WEB=http://grand.central.org/dl/cellservdb/CellServDB
+
+During the Open AFS installation process the user will be presented
+with two choices for the CellServDB: Local copy (CELLSERVDB_INSTALL) and
+one that can be downloaded from the web (CELLSERVDB_WEB).
+
+HINT: The product version number (AFSPRODUCT_VERSION) can be changed to
+create a new version number. For example if you have added source
+changes to OpenAFS-1.2.2a and you wanted to create a new version level,
+you may want to use the following: AFSPRODUCT_VERSION=1.2.2b
+
+STEP G. Begin the build
+
+(1) From Windows 2000 open up a DOS prompt window.
+
+(2) Clean the work area.
+
+ nmake /f NTMakefile clean
+
+(3) Build the complete Windows NT/2000 development environment.
+
+ nmake /f NTMakefile install
+
+While the build is running you will see many compile warnings. This
+behavior is normal; the build process is successful as long as the build
+process doesn't terminate with an error ("nmake.exe return code 0x2")
+and it displays 'Build Finished Successfully'.
+
+STEP H. Install InstallShield (optional).
+
+In order to build an install package for OpenAFS, InstallShield 5.5
+must be installed along with InstallShield East and West
+multi-Language packs.
+
+(1) Install InstallShield (version between 5.0 and 5.5)
+
+For minimum installation choose "compact".
+
+(2) Install West Language Pack (5.5)
+
+(3) Install East Language Pack (5.5)
+
+NOTE: InstallShield's versions 6 and higher WILL NOT WORK for
+Windows NT/2000 build process.
+
+(4) Add necessary DLL's to work with the InstallShield package.
+
+Two Microsoft DLL's are missing from the InstallShield package. These
+DLL's must be copied to Y:\DEST\WinInstall\Config\:
+ SHLWAPI.DLL
+ WININET.DLL
+
+These files are only used during the installation, and they will not
+be left on the target machine. They can be located at
+%SystemRoot%\SYSTEM32.
+
+From a DOS command prompt window enter the following commands:
+
+copy %systemRoot%\System32\SHLWAPI.DLL y:\dest\wininstall\config\.
+copy %systemRoot%\System32\WININET.DLL y:\dest\wininstall\config\.
+
+(5) Add two Environment variables to the bottom of the batch file,
+SETAFS.BAT (see STEP E:).
+
+SET IS5ROOT="C:\Program Files\InstallShield\InstallShield 5.5 Professional Edition"
+SET AFSDEV_INCLUDE=%AFSDEV_INCLUDE%;%IS5ROOT%\Include
+
+STEP I. Build Win2000 InstallShield package
+
+From the DOS command prompt window run:
+
+ Y:
+ nmake /f NTMakefile media
+
+While the build is running you will see a few compile warnings. This
+behavior is normal; the build process is successful as long as the build
+process doesn't terminate with an error ("nmake.exe return code 0x2")
+and it displays 'Install Script Finished Successfully'.
+
+STEP J. Build Win2000 InstallShield package for the Web
+
+InstallShield's PackageForTheWeb combines the installation files into a
+single application file that will expand on execution and lead you
+through the OpenAFS installation.
+
+Install PackageForTheWeb 3 from InstallShield
+
+Add Environment variables to the bottom of the batch file, SETAFS.BAT
+(see STEP E:).
+
+SET ISWEB="C:\Program Files\InstallShield\PackageForTheWeb 3"
+
+From the DOS command prompt window run:
+
+ Y:
+ nmake /f NTMakefile media
+
+While the build is running you will see a few compile warnings. This
+behavior is normal; the build process is successful as long as the build
+process doesn't terminate with an error ("nmake.exe return code 0x2") and
+it displays 'Install Script Finished Successfully'.
+
+HINT: It is only necessary to run "nmake /f NTMakefile media" once, by
+combining steps I & J.
+
+STEP K. Final Results
+
+The build process generates its binaries in Y:\DEST. The subdirectory
+would look like the following:
+
+Y:\DEST
+ bin
+ etc
+ include
+ lib
+ root.client
+ root.server
+ WinInstall
+
+Y:\DEST\Bin - contains build utilities.
+Y:\DEST\root.client - contains Open AFS binaries
+Y:\DEST\root.server - contain Open AFS Server binaries
+Y:\DEST\WinInstall\PackageWeb\AFSforWindows.exe - is the Web install
+package for Open AFS.
+Y:\DEST\WinInstall\ - are the install package files for Open AFS
+
+Step L. Creating a Debug Environment
+
+Instructions on building a debugging environment from Visual Studio C++
+workspace. This example give the user a way to step through the source
+code for AFSCREDS.EXE.
+
+These instructions are to be followed after you have set up the
+development environment.
+
+The following steps must be done before you can build a debug
+environment:
+
+1. Set up the development environment as described above
+2. set AFS_BUILDTYPE=CHECKED to get debug information.
+3. You must use environment variables in System Properties
+4. Do a complete build.
+
+To set the the environment variables in the System Properties:
+1. Select the 'System' icon in the control Panel
+2. Select the 'Advanced' tab
+3. Select the 'Environment Variables' button
+4. In the user area set all variables as you did above that
+were used in the setafs.bat file.
+
+To build a new work space to debug afs_creds.exe:
+
+1. Create New Workspace -
+Select from Microsoft Visual C++ toolbar file New
+Select from 'new' Project Tab Makefile Project name: Creds
+Location Y:\src\winnt\client_creds
+Select OK
+
+From Dialog Box 'Makefile - Step 1 of 2'
+command line= nmake /f"ntmakefile" install
+Output = y:\dest\root.client\usr\vice\etc\AFSCREDS.EXE
+Select NEXT
+
+Dialog Box 'Makefile - Step 2 of 2'
+Command line= nmake /f"ntmakefile" install
+Output = y:\dest\root.client\usr\vice\etc\AFSCREDS.EXE
+
+Select Finish
+
+Switch to FileView
+Right click on 'Source Files' and select 'Add Files to folder', select
+all *.cpp files.
+
+Right click on 'Header Files' and select 'Add Files to folder', select
+all *.h files.
+
+Right click on 'creds files' and select 'New Folder'
+Fill name in 'Build'
+
+From the toolbar select Build
+Select 'Build All'
+
+You should see the following string when the compile is finished:
+"afs_creds.exe - 0 errors(0), 0 warnings(s)"
+
+Press <F5> to execute afs_creds.exe.
+
+STEP M. Optional Items
+
+The build process has an error table that is compiled for many OpenAFS
+applications. This table is generated by Unix based tools. It is not
+normally necessary to modify this table so pre-generated source files
+are included in the OpenAFS source. If you need to make modifications
+in these areas the Unix base tools that run on Windows can be found on
+the web. For example:
+
+ http://cygwin.com/
+
+Below is a short explanation how to update the error table.
+
+(1) Install flex and bison from a Unix based tool provider.
+
+(2) Make changes to the source files.
+
+There are two files in the source tree that are processed with lex
+and yacc on UNIX systems, src/comerr/et_lex.lex.l and
+src/comerr/error_table.y, that when processed produce the files
+et_lex.lex_nt.c, error_table_nt.c, and error_table_nt.h.
+
+Since NT does not include lex and yacc or any equivalent tools, we
+have provided the output files that lex and yacc produce (using Win32
+ports of flex and bison). This will allow builds to work for anyone
+who does not need to change the .l and .y files.
+
+If you do need to change et_lex.lex.l, then you will need to install
+Win32 port of flex on your system. Put flex.exe in a directory on the
+path and rebuild.
+
+If you do need to change error_table.y, then you will need to install
+a Win32 port of bison on your system. Put bison.exe in a directory on
+the path, configure bison as explained in step 5, and rebuild.
+
+You can also attempt to use other replacements for lex and yacc. This
+will require modifying the LEX and YACC settings in
+/config/NTMakefile.i386_nt40. If the replacements require different
+command line options than flex and bison, then you may also need to
+change src/comerr/NTMakefile.
+
+(3) Generate new OpenAFS binaries
+
+
+STEP N. Required patches for 1.2.2a and earlier releases
+
+There are two set of patches must be applied to 1.2.2a source to
+successfully build the binaries:
+
+(1) Patches applied to 1.2.2a to build binaries, excluding install
+package.
+
+diff -Nur --exclude-from=exclude bas/src/NTMakefile upd/src/NTMakefile
+--- bas/src/NTMakefile Wed Nov 14 19:38:06 2001
++++ upd/src/NTMakefile Mon Dec 3 14:41:12 2001
+@@ -471,6 +471,7 @@
+ $(CD) $(OBJ)\$@
+ $(NTMAKE)
+ $(CD) ..\..
++ echo Build Finished Successfully
+
+ install: start finale
+
+@@ -487,6 +488,7 @@
+ $(CD) ..\..\..\..
+
+ media: InstallShield5
++ echo Install Script Finished Successfully
+
+
+(2) Patches applied to 1.2.2a to build install package.
+
+diff -Nur --exclude-from=exclude bas/src/WINNT/afsd/NTMakefile upd/src/WINNT/afsd/NTMakefile
+--- bas/src/WINNT/afsd/NTMakefile Tue Nov 20 22:45:40 2001
++++ upd/src/WINNT/afsd/NTMakefile Wed Dec 5 11:42:46 2001
+@@ -169,8 +169,8 @@
+ $(EXEDIR)\tokens.exe \
+ $(EXEDIR)\unlog.exe $(EXEDIR)\afsd.exe $(EXEDIR)\afsd_service.exe \
+ $(EXEDIR)\fs.exe $(EXEDIR)\symlink.exe \
+- $(LOGON_DLLFILE) $(LOG95_DLLFILE) \
+- $(EXEDIR)\afsshare.exe \
++ $(LOGON_DLLFILE) \
++ $(EXEDIR)\afsshare.exe \
+ $(DESTDIR)\bin\kpasswd.exe
+
+ install9X: install_headers $(CONF_DLLFILE) \
+
+diff -Nur --exclude-from=exclude bas/src/WINNT/install/InstallShield5/NTMakefile upd/src/WINNT/install/InstallShield5/NTMakefile
+--- bas/src/WINNT/install/InstallShield5/NTMakefile Wed Nov 14 19:38:50 2001
++++ upd/src/WINNT/install/InstallShield5/NTMakefile Mon Dec 3 16:43:08 2001
+@@ -60,7 +60,7 @@
+ $(MKDIR) $(DESTDIR)\Wininstall\PackageWeb
+ ! ENDIF
+ $(DEL) /q $(DESTDIR)\Wininstall\PackageWeb\*.*
+- $(ISWEB)\Pftwwiz.exe $(AFSROOT)\src\winnt\install\InstallShield5\PackageWeb.pfw -s -a
++ "$(ISWEB)\Pftwwiz.exe" $(AFSROOT)\src\winnt\install\InstallShield5\PackageWeb.pfw -s -a
+ !ENDIF
+ xcopy /s/e/y "Media\OpenAFS\Disk Images\disk1\*.*" $(DESTDIR)\WinInstall
+ copy AFS_component_version_number.txt $(DESTDIR)\WinInstall\Version.txt
+diff -Nur --exclude-from=exclude bas/src/WINNT/afs_setup_utils/_isuser/_IsUser.RC upd/src/WINNT/afs_setup_utils/_isuser/_IsUser.RC
+--- bas/src/WINNT/afs_setup_utils/_isuser/_IsUser.RC Thu Sep 6 20:54:58 2001
++++ upd/src/WINNT/afs_setup_utils/_isuser/_IsUser.RC Mon Dec 3 15:11:46 2001
+@@ -10,7 +10,7 @@
+ #define APSTUDIO_HIDDEN_SYMBOLS
+ #include "windows.h"
+ #undef APSTUDIO_HIDDEN_SYMBOLS
+-#include <.\sdrc.h>
++#include <sdrc.h>
+
+ /////////////////////////////////////////////////////////////////////////////
+ #undef APSTUDIO_READONLY_SYMBOLS
+diff -Nur --exclude-from=exclude bas/src/WINNT/afs_setup_utils/_isuser/_IsUser.dep upd/src/WINNT/afs_setup_utils/_isuser/_IsUser.dep
+--- bas/src/WINNT/afs_setup_utils/_isuser/_IsUser.dep Thu Sep 6 20:54:58 2001
++++ upd/src/WINNT/afs_setup_utils/_isuser/_IsUser.dep Wed Dec 31 16:00:00 1969
+@@ -1,5 +0,0 @@
+-# Microsoft Developer Studio Generated Dependency File, included by _IsUser.mak
+-
+-.\_Isuser.RC : \
+- ".\sdrc.h"\
+-
+diff -Nur --exclude-from=exclude bas/src/WINNT/afs_setup_utils/_isuser/ntmakefile upd/src/WINNT/afs_setup_utils/_isuser/ntmakefile
+--- bas/src/WINNT/afs_setup_utils/_isuser/ntmakefile Mon Sep 10 09:39:50 2001
++++ upd/src/WINNT/afs_setup_utils/_isuser/ntmakefile Mon Dec 3 15:16:04 2001
+@@ -30,14 +30,6 @@
+ "$(OUTDIR)" ::
+ if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
+
+-HEADERS = ".\sdrc.h"
+-
+-".\sdrc.h" : $(IS5ROOT)\INCLUDE\sdrc.h
+- $(COPY) $(IS5ROOT)\INCLUDE\sdrc.h .
+-! IF EXIST($(IS5ROOT)\Script\ISRT\Include\sdrc.h)
+- $(COPY) $(IS5ROOT)\Script\ISRT\Include\sdrc.h .
+-! ENDIF
+-
+ CPP=cl.exe
+ CPP_PROJ=/nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "_ISUSER_EXPORTS" /YX /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\\" /FD /c
+
+@@ -85,20 +77,10 @@
+ "$(INTDIR)\_isuser.obj" \
+ "$(INTDIR)\_Isuser.res"
+
+-"$(OUTDIR)\_IsUser.dll" : "$(OUTDIR)" $(HEADERS) $(DEF_FILE) $(LINK32_OBJS)
++"$(OUTDIR)\_IsUser.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
+ $(LINK32) @<<
+ $(LINK32_FLAGS) $(LINK32_OBJS)
+ <<
+-
+-
+-!IF "$(NO_EXTERNAL_DEPS)" != "1"
+-!IF EXISTS("_IsUser.dep")
+-!INCLUDE "_IsUser.dep"
+-!ELSE
+-!MESSAGE Warning: cannot find "_IsUser.dep"
+-!ENDIF
+-!ENDIF
+-
+
+ SOURCE=.\_isuser.c
# License. For details, see the LICENSE file in the top-level source
# directory or online at http://www.openafs.org/dl/license10.html
+AFSDEV_AUXCDEFINES = $(AFSDEV_AUXCDEFINES) /D"_AFXDLL"
AFSDEV_NETGUI = 1
RELDIR=WINNT\afsd
!INCLUDE ..\..\config\NTMakefile.$(SYS_NAME)
INCFILEDIR = $(DESTDIR)\include\afs # header file install directory
+# afsdicon and below added for WINNT\extra support
+
INCFILES =\
$(INCFILEDIR)\afsd.h \
$(INCFILEDIR)\cm.h \
!IFDEF OSICRASH
$(INCFILEDIR)\afsdcrash.h \
!ENDIF
- $(INCFILEDIR)\cm_dns_private.h
+ $(INCFILEDIR)\cm_dns_private.h \
+ $(INCFILEDIR)\lanahelper.h \
+ $(INCFILEDIR)\afsdicon.h \
+ $(INCFILEDIR)\cm_callback.h \
+ $(INCFILEDIR)\cm_aclent.h \
+ $(INCFILEDIR)\cm_volume.h \
+ $(INCFILEDIR)\cm_dcache.h \
+ $(INCFILEDIR)\cm_access.h \
+ $(INCFILEDIR)\cm_vnodeops.h \
+ $(INCFILEDIR)\cm_dir.h \
+ $(INCFILEDIR)\cm_utils.h \
+ $(INCFILEDIR)\cm_daemon.h \
+ $(INCFILEDIR)\cm_ioctl.h \
+ $(INCFILEDIR)\cm_dnlc.h \
+ $(INCFILEDIR)\cm_buf.h \
+ $(INCFILEDIR)\cm_freelance.h \
+ $(INCFILEDIR)\afsd_eventlog.h \
+ $(INCFILEDIR)\afsd_eventmessages.h
IDLFILES =\
- afsrpc.h $(OUT)\afsrpc_c.c
+ afsrpc.h $(OUT)\afsrpc_c.obj
CONFOBJS=$(OUT)\cm_config.obj \
$(OUT)\cm_dns.obj
!IFDEF OSICRASH
$(OUT)\afsdcrash.obj \
!ENDIF
- $(OUT)\cm_freelance.obj
+ $(OUT)\cm_freelance.obj \
+ $(OUT)\lanahelper.obj \
+ $(OUT)\afsd_eventlog.obj \
+ $(OUT)\afsd_flushvol.obj
+
+$(AFSDOBJS):
$(OUT)\cm_conn.obj: cm_conn.c
- $(C2OBJ) -DAFS_PTHREAD_ENV $**
+ $(C2OBJ) -DAFS_PTHREAD_ENV /Fo$@ $**
FSOBJS=$(OUT)\fs.obj $(OUT)\fs_utils.obj
ILIBDIR = $(DESTDIR)\lib
+#
+# Rules for message compiler info for logging events
+#
+$(INCFILEDIR)\afsd_eventmessages.h: afsd_eventmessages.mc
+ mc afsd_eventmessages.mc
+
############################################################################
#
# Flags for linking LOGON DLL'S
CONF_DLLFILE = $(DESTDIR)\root.client\usr\vice\etc\libafsconf.dll
CONF_DLLLIBS = \
+ dnsapi.lib \
$(DESTDIR)\lib\afs\afsutil.lib \
$(DESTDIR)\lib\afs\afsreg.lib
$(OUT)\afslogon.res
LOGON_DLLLIBS =\
+ dnsapi.lib \
$(DESTDIR)\lib\afsauthent.lib \
$(DESTDIR)\lib\libafsconf.lib
$(OUT)\afslog95.res
LOG95_DLLLIBS =\
+ dnsapi.lib \
$(DESTDIR)\lib\afsauthent.lib \
$(DESTDIR)\lib\libafsconf.lib
# assorted exe's
EXELIBS = \
+ dnsapi.lib \
$(DESTDIR)\lib\afs\afsauth.lib \
$(DESTDIR)\lib\afs\afskauth.lib \
$(DESTDIR)\lib\afs\afsprot.lib \
AFSD_EXELIBS =\
largeint.lib \
netapi32.lib \
- mpr.lib \
+ mpr.lib \
+ dnsapi.lib \
$(DESTDIR)\lib\libosi.lib \
$(DESTDIR)\lib\afsrpc.lib \
+ $(DESTDIR)\lib\afsrx.lib \
$(DESTDIR)\lib\afsauthent.lib \
$(DESTDIR)\lib\afs\mtafsvldb.lib \
$(DESTDIR)\lib\afs\mtafsint.lib \
# afsd_service.exe
$(EXEDIR)\afsd_service.exe: $(OUT)\afsd_service.obj $(AFSDOBJS) $(OUT)\afsd_service.res $(RXOBJS)
- $(EXECONLINK) $(AFSD_EXELIBS)
+ $(EXECONLINK) $(AFSD_EXELIBS) /NODEFAULTLIB:libc.lib /MAP
$(EXEPREP)
# fs.exe
KPASSWD_LIBS =\
$(DESTDIR)\lib\afsauthent.lib \
$(DESTDIR)\lib\afsrpc.lib \
+ $(DESTDIR)\lib\afsrx.lib \
$(DESTDIR)\lib\afs\afscmd.lib \
$(DESTDIR)\lib\afsdes.lib \
$(DESTDIR)\lib\afs\afsutil.lib
$(OUT)\kpasswd.obj: $(KAUTH)/kpasswd.c
- $(C2OBJ) -DAFS_PTHREAD_ENV $**
+ $(C2OBJ) -DAFS_PTHREAD_ENV /Fo$@ $**
$(OUT)\kkids.obj: $(KAUTH)/kkids.c
- $(C2OBJ) -DAFS_PTHREAD_ENV $**
+ $(C2OBJ) -DAFS_PTHREAD_ENV /Fo$@ $**
$(OUT)\kautils.obj: $(KAUTH)/kautils.c
- $(C2OBJ) -DAFS_PTHREAD_ENV $**
+ $(C2OBJ) -DAFS_PTHREAD_ENV /Fo$@ $**
+
+$(OUT)\kpasswd.res: $(KAUTH)\kpasswd.rc
+ $(RC) /Fo$@ $**
$(DESTDIR)\bin\kpasswd.exe: $(KPASSWD_OBJS) $(KPASSWD_LIBS)
$(DEL) $(DESTDIR)\bin\kpasswd.exe
############################################################################
# generate versioninfo resources
-$(OUT)\afsshare.res: AFS_component_version_number.h
+$(OUT)\afsshare.res: afsshare.rc AFS_component_version_number.h
-$(OUT)\fs.res: AFS_component_version_number.h
+$(OUT)\fs.res: fs.rc AFS_component_version_number.h
-$(OUT)\symlink.res: AFS_component_version_number.h
+$(OUT)\symlink.res: symlink.rc AFS_component_version_number.h
-$(OUT)\klog.res: AFS_component_version_number.h
+$(OUT)\klog.res: klog.rc AFS_component_version_number.h
-$(OUT)\tokens.res: AFS_component_version_number.h
+$(OUT)\tokens.res: tokens.rc AFS_component_version_number.h
-$(OUT)\unlog.res: AFS_component_version_number.h
+$(OUT)\unlog.res: unlog.rc AFS_component_version_number.h
-$(OUT)\afsd_service.res: AFS_component_version_number.h
+afsd_eventmessages.rc: afsd_eventmessages.h
-$(OUT)\afslogon.res: AFS_component_version_number.h
+$(OUT)\afsd_service.res: afsd_service.rc afsd_eventmessages.rc AFS_component_version_number.h
-$(OUT)\afslog95.res: AFS_component_version_number.h
+$(OUT)\afslogon.res: afslogon.rc AFS_component_version_number.h
-$(OUT)\libafsconf.res: AFS_component_version_number.h
+$(OUT)\afslog95.res: afslog95.rc AFS_component_version_number.h
+$(OUT)\libafsconf.res: libafsconf.rc AFS_component_version_number.h
+
+############################################################################
clean::
$(DEL) $(OUT)\*.res
$(DEL) afsrpc.h
$(DEL) afsrpc_?.*
+ $(DEL) afsd_eventmessages.h
$(DEL) $(CONF_DLLFILE)
$(DEL) $(LOGON_DLLFILE)
$(DEL) $(LOG95_DLLFILE)
--- /dev/null
+////////////////////////////////////////////////////////////////////
+//
+//
+// E V E N T L O G G I N G F U N C T I O N S
+//
+//
+////////////////////////////////////////////////////////////////////
+
+
+#include <windows.h>
+#include <stdarg.h>
+#include <string.h>
+#include "afsd_eventlog.h"
+
+#define SZSERVICEPATH "System\\CurrentControlSet\\Services\\"
+#define SZSERVICENAME "TransarcAFSDaemon"
+
+static CHAR szKeyName[] = "System\\CurrentControlSet\\Services\\EventLog\\Application\\TransarcAFSDaemon";
+
+static BOOL GetServicePath(LPTSTR lpPathBuf, PDWORD pdwPathBufSize);
+static BOOL AddEventSource(void);
+
+static BOOL
+GetServicePath(LPTSTR lpPathBuf, PDWORD pdwPathBufSize)
+{
+ HKEY hKey = NULL;
+ UCHAR szBuf[MAX_PATH];
+ DWORD dwData = 0;
+ BOOL bRet = TRUE;
+
+ do {
+ // Prepare path in Registry
+ memset(szBuf, '\0', MAX_PATH);
+ strcpy(szBuf, SZSERVICEPATH);
+ strcat(szBuf, "TransarcAFSDaemon");
+
+ // Open key
+ if ( RegOpenKeyEx( HKEY_LOCAL_MACHINE, szBuf, 0, KEY_QUERY_VALUE, &hKey ) )
+ {
+ bRet = FALSE;
+ break;
+ }
+
+ // prepare user's buffer and read into it
+ dwData = *pdwPathBufSize;
+ memset(lpPathBuf, '\0', dwData);
+ if ( RegQueryValueEx(
+ hKey, // handle to key
+ "ImagePath", // value name
+ NULL, // reserved
+ NULL, // type buffer
+ (LPBYTE) lpPathBuf, // data buffer
+ &dwData)) // size of data buffer
+ {
+ bRet = FALSE;
+ break;
+ }
+
+ *pdwPathBufSize = dwData;
+
+ } while (0);
+
+ if (hKey != NULL)
+ RegCloseKey(hKey);
+
+ return bRet;
+}
+
+//
+// Ensure name for message file is in proper location in Registry.
+//
+static BOOL
+AddEventSource()
+{
+ HKEY hKey = NULL;
+ UCHAR szBuf[MAX_PATH];
+ DWORD dwData, dwDisposition;
+ BOOL bRet = TRUE;
+
+ do {
+ // Let's see if key already exists as a subkey under the
+ // Application key in the EventLog registry key. If not,
+ // create it.
+ if ( RegOpenKeyEx( HKEY_LOCAL_MACHINE, szKeyName, 0,
+ KEY_QUERY_VALUE, &hKey ) )
+ {
+ // nope - create it
+ if ( RegCreateKeyEx(HKEY_LOCAL_MACHINE, szKeyName, 0,
+ NULL, REG_OPTION_NON_VOLATILE,
+ KEY_ALL_ACCESS, NULL, &hKey,
+ &dwDisposition))
+ {
+ bRet = FALSE;
+ break;
+ }
+
+ // Set the name of the message file
+ // Get "ImagePath" from TransarcAFSDaemon service
+ memset(szBuf, '\0', MAX_PATH);
+ dwData = MAX_PATH;
+ GetServicePath(szBuf, &dwData);
+
+ // Add the name to the EventMessageFile subkey.
+ if ( RegSetValueEx(
+ hKey, // subkey handle
+ "EventMessageFile", // value name
+ 0, // must be zero
+ REG_EXPAND_SZ, // value type
+ (LPBYTE) szBuf, // pointer to value data
+ strlen(szBuf) + 1)) // length of value data
+ {
+ bRet = FALSE;
+ break;
+ }
+
+ // Set the supported event types in the TypesSupported subkey.
+ dwData = EVENTLOG_ERROR_TYPE | EVENTLOG_WARNING_TYPE |
+ EVENTLOG_INFORMATION_TYPE;
+
+ if ( RegSetValueEx(
+ hKey, // subkey handle
+ "TypesSupported", // value name
+ 0, // must be zero
+ REG_DWORD, // value type
+ (LPBYTE) &dwData, // pointer to value data
+ sizeof(DWORD))) // length of value data
+ {
+ bRet = FALSE;
+ break;
+ }
+ }
+
+ else
+ {
+ // key was opened - read it
+ memset(szBuf, '\0', MAX_PATH);
+ dwData = MAX_PATH;
+ if ( RegQueryValueEx(
+ hKey, // handle to key
+ "EventMessageFile", // value name
+ NULL, // reserved
+ NULL, // type buffer
+ (LPBYTE) szBuf, // data buffer
+ &dwData)) // size of data buffer
+ {
+ bRet = FALSE;
+ break;
+ }
+ }
+
+ } while (0);
+
+ if (hKey != NULL)
+ RegCloseKey(hKey);
+
+ return bRet;
+}
+
+// Log an event with a formatted system message as the (only) substitution
+// string, from the given message ID.
+VOID
+LogEventMessage(WORD wEventType, DWORD dwEventID, DWORD dwMessageID)
+{
+ LPTSTR msgBuf;
+
+ FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM
+ | FORMAT_MESSAGE_ALLOCATE_BUFFER,
+ NULL, dwMessageID, 0, (LPTSTR)&msgBuf, 0, NULL);
+ LogEvent(wEventType, dwEventID, msgBuf, NULL);
+ LocalFree(msgBuf);
+}
+
+//
+// Use the ReportEvent API to write an entry to the system event log.
+//
+#define MAXSTRINGARGS 100
+VOID
+LogEvent(WORD wEventType, DWORD dwEventID, LPTSTR lpString, ...)
+{
+ va_list listStrings;
+ HANDLE hEventSource;
+ LPTSTR lpStrings[MAXSTRINGARGS];
+ WORD wNumStrings;
+
+ // Ensure that our event source is properly initialized.
+ if (!AddEventSource())
+ return;
+
+ // Get a handle to the event log.
+ hEventSource = RegisterEventSource(NULL, SZSERVICENAME);
+ if (hEventSource == NULL)
+ return;
+
+ // Construct the array of substitution strings.
+ va_start(listStrings, lpString);
+ for (wNumStrings = 0;
+ lpString != NULL && wNumStrings < MAXSTRINGARGS;
+ wNumStrings++)
+ {
+ lpStrings[wNumStrings] = lpString;
+ // Advance to the next argument.
+ lpString = va_arg(listStrings, LPTSTR);
+ }
+ va_end(listStrings);
+
+ // Make sure we were not given too many args.
+ if (wNumStrings >= MAXSTRINGARGS)
+ return;
+
+ // Log the event.
+ ReportEvent(hEventSource, // handle of event source
+ wEventType, // event type
+ 0, // event category
+ dwEventID, // event ID
+ NULL, // current user's SID
+ wNumStrings, // strings in lpszStrings
+ 0, // no bytes of raw data
+ lpStrings, // array of error strings
+ NULL); // no raw data
+
+ DeregisterEventSource(hEventSource);
+}
--- /dev/null
+// This header contains needed definitions and declarations for afsd's
+// event logging functions.
+
+#ifndef __AFSD_EVENTLOG_H_
+#define __AFSD_EVENTLOG_H_ 1
+
+// Include the event log message definitions.
+#include "afsd_eventmessages.h"
+
+VOID LogEventMessage(WORD wEventType, DWORD dwEventID, DWORD dwMessageID);
+VOID LogEvent(WORD wEventType, DWORD dwEventID, LPTSTR lpString, ...);
+
+#endif /* __AFSD_EVENTLOG_H_ */
--- /dev/null
+;//
+;// afsd_eventmessages.mc
+;//
+;// This file contains the message definitions for the
+;// TransarcAFSDaemon service to facilitate system event logging.
+;//
+;//
+;
+;#ifndef __AFSD_EVENTMESSAGES_H_
+;#define __AFSD_EVENTMESSAGES_H_ 1
+
+MessageIdTypedef=DWORD
+
+SeverityNames=(Success=0x0:STATUS_SEVERITY_SUCCESS
+ Informational=0x1:STATUS_SEVERITY_INFORMATIONAL
+ Warning=0x2:STATUS_SEVERITY_WARNING
+ Error=0x3:STATUS_SEVERITY_ERROR
+ )
+
+FacilityNames=(System=0x0:FACILITY_SYSTEM
+ Runtime=0x2:FACILITY_RUNTIME
+ Stubs=0x3:FACILITY_STUBS
+ Io=0x4:FACILITY_IO_ERROR_CODE
+ )
+
+LanguageNames=(English=0x409:MSG00409)
+
+MessageId=0x1
+Severity=Informational
+Facility=System
+SymbolicName=MSG_TIME_FLUSH_PER_VOLUME
+Language=English
+Elapsed time to flush AFS volume <%1> = %2 milliseconds.
+.
+
+MessageId=
+Severity=Informational
+Facility=System
+SymbolicName=MSG_TIME_FLUSH_TOTAL
+Language=English
+Total elapsed time to flush %1 AFS volume(s) = %2 milliseconds.
+.
+
+MessageId=
+Severity=Error
+Facility=System
+SymbolicName=MSG_FLUSH_NO_SHARE_NAME
+Language=English
+Cannot get AFS share name to flush volumes.
+.
+
+MessageId=
+Severity=Error
+Facility=System
+SymbolicName=MSG_FLUSH_BAD_SHARE_NAME
+Language=English
+Invalid share name %1; cannot flush volumes.
+.
+
+MessageId=
+Severity=Error
+Facility=System
+SymbolicName=MSG_FLUSH_NO_MEMORY
+Language=English
+Insufficient memory to flush volumes.
+.
+
+MessageId=
+Severity=Error
+Facility=System
+SymbolicName=MSG_FLUSH_OPEN_ENUM_ERROR
+Language=English
+Cannot open enumeration of network resources: %1
+.
+
+MessageId=
+Severity=Error
+Facility=System
+SymbolicName=MSG_FLUSH_ENUM_ERROR
+Language=English
+Cannot enumerate network resources: %1
+.
+
+MessageId=
+Severity=Warning
+Facility=System
+SymbolicName=MSG_FLUSH_FAILED
+Language=English
+Failed to flush volume %1.
+.
+
+MessageId=
+Severity=Error
+Facility=System
+SymbolicName=MSG_FLUSH_IMPERSONATE_ERROR
+Language=English
+Failed to impersonate logged-on user.
+.
+
+MessageId=
+Severity=Warning
+Facility=System
+SymbolicName=MSG_FLUSH_UNEXPECTED_EVENT
+Language=English
+Flush volumes thread received unrecognized event.
+.
+
+
+;#endif /* __AFSD_EVENTMESSAGES_H_ 1 */
--- /dev/null
+LANGUAGE 0x9,0x1
+1 11 MSG00409.bin
--- /dev/null
+//
+// AFSD_FLUSHVOL.C
+//
+// Routines to handle flushing AFS volumes in response to
+// System Power event notification such as Hibernate request.
+//
+/////////////////////////////////////////////////////////////////////
+
+#include <afs/param.h>
+#include <afs/stds.h>
+
+#include <windows.h>
+
+#include <string.h>
+#include <setjmp.h>
+#include "afsd.h"
+#include "afsd_init.h"
+#include "smb.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <malloc.h>
+
+#include <winsock2.h>
+
+#include <osi.h>
+
+#include "afsd_flushvol.h"
+#include "afsd_eventlog.h"
+
+static FLUSHVOLTHREADINFO gThreadInfo = {0};
+static HANDLE gThreadHandle = NULL;
+
+
+/////////////////////////////////////////////////////////////////////
+//
+// Call routine found in FS.EXE to flush volume.
+//
+// At entry, input param is UNC string for volume,
+// e.g. '\\afs\all\athena.mit.edu\user\m\h\mholiday'
+//
+// I believe that success from 'pioctl' routine
+// indicated by return value of zero (0).
+//
+afs_int32
+afsd_ServicePerformFlushVolumeCmd(char *data)
+{
+ register afs_int32 code;
+ struct ViceIoctl blob;
+
+ memset(&blob, '\0', sizeof(blob));
+ code = pioctl(data, VIOC_FLUSHVOLUME, &blob, 0);
+
+ return code;
+}
+
+BOOL
+afsd_ServicePerformFlushVolumes()
+{
+ CONST CHAR COLON = ':';
+ CONST CHAR SLASH = '\\';
+ CONST DWORD NETRESBUFSIZE = 16384;
+ CHAR bufMessage[1024];
+ UINT i;
+ DWORD dwServerSize;
+ DWORD dwRet;
+ DWORD dwCount;
+ DWORD dwNetResBufSize;
+ DWORD dwTotalVols = 0;
+ DWORD dwVolBegin, dwVolEnd;
+ DWORD dwFlushBegin, dwFlushEnd;
+ HANDLE hEnum;
+ LPNETRESOURCE lpNetResBuf, lpnr;
+ PCHAR pszShareName, pc;
+ afs_int32 afsRet = 0;
+
+ // Determine the root share name (\\AFS\ALL or \\<machine>-AFS\ALL),
+ // and the length of the server name prefix.
+ pszShareName = smb_GetSharename();
+ if (pszShareName == NULL)
+ {
+ LogEvent(EVENTLOG_ERROR_TYPE, MSG_FLUSH_NO_SHARE_NAME, NULL);
+ return FALSE;
+ }
+ pc = strrchr(pszShareName, SLASH);
+ if ((pc == NULL) || ((dwServerSize = pc - pszShareName) < 3))
+ {
+ LogEvent(EVENTLOG_ERROR_TYPE, MSG_FLUSH_BAD_SHARE_NAME,
+ pszShareName, NULL);
+ free(pszShareName);
+ return FALSE;
+ }
+
+ // Allocate a buffer to hold network resources returned by
+ // WNetEnumResource().
+ lpNetResBuf = malloc(NETRESBUFSIZE);
+ if (lpNetResBuf == NULL)
+ {
+ // Out of memory, give up now.
+ LogEvent(EVENTLOG_ERROR_TYPE, MSG_FLUSH_NO_MEMORY, NULL);
+ free(pszShareName);
+ return FALSE;
+ }
+
+ // Initialize the flush timer. Note that GetTickCount() returns
+ // the number of milliseconds since the system started, in a DWORD,
+ // so that the value wraps around every 49.7 days. We do not bother
+ // to handle the case where the flush elapsed time is greater than
+ // that.
+ dwFlushBegin = GetTickCount();
+
+ dwRet = WNetOpenEnum(RESOURCE_CONNECTED, RESOURCETYPE_ANY, 0, NULL,
+ &hEnum);
+ if (dwRet != NO_ERROR)
+ {
+ LogEventMessage(EVENTLOG_ERROR_TYPE, MSG_FLUSH_OPEN_ENUM_ERROR,
+ dwRet);
+ free(pszShareName);
+ return FALSE;
+ }
+
+ // Loop to enumerate network resources, and flush those associated
+ // with AFS volumes.
+ while (1)
+ {
+ dwCount = -1;
+ memset(lpNetResBuf, 0, NETRESBUFSIZE);
+ dwNetResBufSize = NETRESBUFSIZE;
+ dwRet = WNetEnumResource(hEnum, &dwCount,
+ lpNetResBuf, &dwNetResBufSize);
+ if (dwRet != NO_ERROR)
+ break;
+ // Iterate over the returned network resources.
+ for (i = 0, lpnr = lpNetResBuf; i < dwCount; i++, lpnr++)
+ {
+ // Ensure resource has a remote name, and is connected.
+ if ((lpnr->lpRemoteName == NULL) ||
+ (lpnr->dwScope != RESOURCE_CONNECTED))
+ continue;
+ if ((_strnicmp(lpnr->lpRemoteName, pszShareName,
+ dwServerSize) == 0) &&
+ (lpnr->lpRemoteName[dwServerSize] == SLASH))
+ {
+ // got one!
+ // but we don't want to flush '\\[...]afs\all'
+ if (_stricmp(lpnr->lpRemoteName,
+ pszShareName) == 0)
+ continue;
+ ++dwTotalVols;
+
+ dwVolBegin = GetTickCount();
+ afsRet = afsd_ServicePerformFlushVolumeCmd(lpnr->lpRemoteName);
+ dwVolEnd = GetTickCount();
+ if (afsRet == 0)
+ {
+ LogTimingEvent(MSG_TIME_FLUSH_PER_VOLUME,
+ lpnr->lpRemoteName,
+ dwVolEnd - dwVolBegin);
+ }
+ else
+ {
+ LogEvent(EVENTLOG_WARNING_TYPE,
+ MSG_FLUSH_FAILED,
+ lpnr->lpRemoteName, NULL);
+ }
+ }
+ }
+ }
+ WNetCloseEnum(hEnum);
+ free(lpNetResBuf);
+ free(pszShareName);
+ if (dwRet != ERROR_NO_MORE_ITEMS)
+ {
+ LogEventMessage(EVENTLOG_ERROR_TYPE, MSG_FLUSH_ENUM_ERROR,
+ dwRet);
+ return FALSE;
+ }
+
+ dwFlushEnd = GetTickCount();
+
+ // display total volume count in Event Logger
+ sprintf(bufMessage, "%d", dwTotalVols);
+ LogTimingEvent(MSG_TIME_FLUSH_TOTAL, bufMessage,
+ dwFlushEnd - dwFlushBegin);
+
+ return TRUE;
+}
+
+// Report a timing event to the system event log.
+// The lpszString1 argument is the first substitution string for the
+// given event ID. The time argument will be converted into the
+// second substitution string.
+static VOID
+LogTimingEvent(DWORD dwEventID, LPTSTR lpString1, DWORD dwTime)
+{
+ CHAR szTime[16];
+
+ sprintf(szTime, "%lu", dwTime);
+ LogEvent(EVENTLOG_INFORMATION_TYPE, dwEventID, lpString1, szTime,
+ NULL);
+}
+
+
+/////////////////////////////////////////////////////////////////////
+//
+// GetUserToken
+//
+// Obtain token for the currently logged-in user.
+//
+// This routine looks for a window which we 'know' belongs to
+// the shell, and from there we follow a route which leads to
+// getting a handle on an access token owned by the shell.
+//
+// The return value is either a handle to a suitable token,
+// or else null.
+//
+// One of the times that this function might return null
+// is when there is no logged-in user. Other cases include
+// insufficient access to the desktop, etc.
+//
+// Disclaimer:
+// Portions of this routine found in various newsgroups
+//
+HANDLE GetUserToken(DWORD access)
+{
+ HANDLE hTok = NULL;
+ DWORD pid = 0, tid = 0;
+
+ // Try it the easy way first - look for a window owned by the shell on
+ // our current desktop. If we find one, use that to get the process id.
+ HWND shell = FindWindowEx(NULL, NULL, "Progman", NULL);
+ if (shell != NULL)
+ {
+ tid = GetWindowThreadProcessId(shell, &pid);
+ }
+
+ // We are possibly running on a private window station and desktop: we must
+ // switch to the default (which we suppose is where we will find the
+ // running shell).
+ else
+ {
+ HWINSTA saveWinSta = GetProcessWindowStation();
+ HDESK saveDesk = GetThreadDesktop(GetCurrentThreadId());
+ HWINSTA winSta = NULL;
+ HDESK desk = NULL;
+ BOOL changeFlag = FALSE;
+ BOOL dummy = saveWinSta != NULL &&
+ saveDesk != NULL &&
+ (winSta = OpenWindowStation("WinSta0", FALSE,
+ MAXIMUM_ALLOWED)) != NULL &&
+ (changeFlag = SetProcessWindowStation(winSta)) != 0 &&
+ (desk = OpenDesktop("Default", 0, FALSE,
+ MAXIMUM_ALLOWED)) != NULL &&
+ SetThreadDesktop(desk) != 0;
+
+ // Now find the window and process on this desktop
+ shell = FindWindowEx(NULL, NULL, "Progman", NULL);
+ if (shell != NULL)
+ {
+ tid = GetWindowThreadProcessId(shell, &pid);
+ }
+
+ // Restore our own window station and desktop
+ if (changeFlag)
+ {
+ SetProcessWindowStation(saveWinSta);
+ SetThreadDesktop(saveDesk);
+ }
+
+ // Close temporary objects
+ if (winSta != NULL)
+ CloseWindowStation(winSta);
+ if (desk != NULL)
+ CloseDesktop(desk);
+ }
+
+ //
+ // If we have a process id, use that to get the process handle and
+ // from there the process' access token.
+ //
+ if (pid != 0)
+ {
+ HANDLE hProc = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid);
+ if (hProc != NULL)
+ {
+ OpenProcessToken(hProc, access, &hTok) || (hTok = NULL);
+ CloseHandle(hProc);
+ }
+ }
+
+ // Return token if we got one
+ return hTok;
+}
+
+// impersonate logged-on user as client
+BOOL
+ImpersonateClient()
+{
+ DWORD dwDesiredAccess = TOKEN_ALL_ACCESS;
+ HANDLE hUserToken = GetUserToken(dwDesiredAccess);
+
+ if (hUserToken == NULL)
+ return FALSE;
+ if (ImpersonateLoggedOnUser(hUserToken) == 0)
+ {
+ LogEvent(EVENTLOG_ERROR_TYPE, MSG_FLUSH_IMPERSONATE_ERROR,
+ NULL);
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/////////////////////////////////////////////////////////////////////
+//
+// Thread proc
+//
+DWORD WINAPI
+afsd_ServiceFlushVolumesThreadProc(LPVOID lpParam)
+{
+ FLUSHVOLTHREADINFO ThreadInfo;
+ PFLUSHVOLTHREADINFO pThreadInfo = (PFLUSHVOLTHREADINFO) lpParam;
+ HANDLE arHandles[2] = {0};
+ DWORD dwWaitState = 0;
+
+ // thread running - get handles
+ ThreadInfo.hEventPowerEvent = pThreadInfo->hEventPowerEvent;
+ ThreadInfo.hEventResumeMain = pThreadInfo->hEventResumeMain;
+ ThreadInfo.hEventTerminate = pThreadInfo->hEventTerminate;
+
+ // setup to wait
+ arHandles[0] = ThreadInfo.hEventTerminate;
+ arHandles[1] = ThreadInfo.hEventPowerEvent;
+
+ // do stuff ..
+ while (1)
+ {
+ // wait for an event to happen
+ dwWaitState = WaitForMultipleObjectsEx(2, arHandles, FALSE, INFINITE, FALSE);
+
+ switch (dwWaitState)
+ {
+ case WAIT_OBJECT_0:
+ // termination signaled
+ RevertToSelf();
+ ExitThread(0);
+ break;
+
+ case WAIT_OBJECT_0+1:
+ // Power event
+ // - flush 'em!
+ if (ImpersonateClient())
+ {
+ afsd_ServicePerformFlushVolumes();
+ }
+ // acknowledge event
+ ResetEvent(ThreadInfo.hEventPowerEvent);
+ break;
+
+ case WAIT_ABANDONED_0:
+ case WAIT_ABANDONED_0+1:
+ case WAIT_IO_COMPLETION:
+ case WAIT_TIMEOUT:
+ // sno*
+ LogEvent(EVENTLOG_WARNING_TYPE,
+ MSG_FLUSH_UNEXPECTED_EVENT, NULL);
+ break;
+
+ } // end switch
+
+ // signal back to waiting mainline
+ SetEvent(ThreadInfo.hEventResumeMain);
+
+ } // end while
+
+ // I suppose we never get here
+ ExitThread(0);
+}
+
+/////////////////////////////////////////////////////////////////////
+//
+// Mainline thread routines
+//
+
+VOID
+CheckAndCloseHandle(HANDLE thisHandle)
+{
+ if (thisHandle != NULL)
+ {
+ CloseHandle(thisHandle);
+ thisHandle = NULL;
+ }
+}
+
+//
+// Thread Creation
+//
+BOOL
+PowerNotificationThreadCreate()
+{
+ BOOL bSuccess = FALSE;
+ DWORD dwThreadId = 0;
+
+ do
+ {
+ // create power event notification event
+ // bManualReset=TRUE, bInitialState=FALSE
+ gThreadInfo.hEventPowerEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
+ if (gThreadInfo.hEventPowerEvent == NULL)
+ break;
+
+ // create mainline resume event
+ // bManualReset=FALSE, bInitialState=FALSE
+ gThreadInfo.hEventResumeMain = CreateEvent(NULL, FALSE, FALSE, NULL);
+ if (gThreadInfo.hEventResumeMain == NULL)
+ break;
+
+ // create thread terminate event
+ // bManualReset=FALSE, bInitialState=FALSE
+ gThreadInfo.hEventTerminate = CreateEvent(NULL, FALSE, FALSE, NULL);
+ if (gThreadInfo.hEventTerminate == NULL)
+ break;
+
+ // good so far - create thread
+ gThreadHandle = CreateThread(NULL, 0,
+ afsd_ServiceFlushVolumesThreadProc,
+ (LPVOID) &gThreadInfo,
+ 0, &dwThreadId);
+
+ if (!gThreadHandle)
+ break;
+
+ bSuccess = TRUE;
+
+ } while (0);
+
+
+ if (!bSuccess)
+ {
+ CheckAndCloseHandle(gThreadInfo.hEventPowerEvent);
+ CheckAndCloseHandle(gThreadInfo.hEventResumeMain);
+ CheckAndCloseHandle(gThreadInfo.hEventTerminate);
+ CheckAndCloseHandle(gThreadHandle);
+ }
+
+ return bSuccess;
+}
+
+//
+// Thread Notification
+//
+BOOL
+PowerNotificationThreadNotify()
+{
+ DWORD dwRet = 0;
+ BOOL bRet = FALSE;
+
+ // Notify thread of power event, and wait 19 seconds
+ dwRet = SignalObjectAndWait(
+ gThreadInfo.hEventPowerEvent, // object to signal
+ gThreadInfo.hEventResumeMain, // object to watch
+ 19*1000, // timeout (ms)
+ FALSE // alertable
+ );
+
+ if (dwRet == WAIT_OBJECT_0)
+ bRet = TRUE;
+
+ return bRet;
+}
+
+//
+// Thread Termination
+//
+VOID
+PowerNotificationThreadExit()
+{
+ // ExitThread
+ if (gThreadHandle)
+ {
+ SetEvent(gThreadInfo.hEventTerminate);
+ CloseHandle(gThreadHandle);
+ }
+}
+
--- /dev/null
+//
+// AFSD_FLUSHVOL.H
+//
+// Include file for routines that handle flushing AFS volumes
+// in response to System Power event notification such as
+// Hibernate request.
+//
+/////////////////////////////////////////////////////////////////////
+
+#ifndef _AFSD_FLUSHVOL_H_
+#define _AFSD_FLUSHVOL_H_
+
+#include <Winnetwk.h>
+#include "fs_utils.h"
+
+// handles
+typedef struct _tagFLUSHVOLTHREADINFO {
+ HANDLE hEventPowerEvent;
+ HANDLE hEventResumeMain;
+ HANDLE hEventTerminate;
+} FLUSHVOLTHREADINFO, *PFLUSHVOLTHREADINFO;
+
+// invokes fs.exe pioctl
+static afs_int32 afsd_ServicePerformFlushVolumeCmd(char *data);
+
+// thread callback
+static DWORD WINAPI afsd_ServiceFlushVolumesThreadProc(LPVOID lpParameter);
+
+// helper function
+static VOID CheckAndCloseHandle(HANDLE thisHandle);
+
+// thread construction/notification/destruction
+BOOL PowerNotificationThreadCreate(VOID);
+BOOL PowerNotificationThreadNotify(VOID);
+VOID PowerNotificationThreadExit(VOID);
+
+// impersonation helper(s)
+static HANDLE GetUserToken(DWORD access);
+static BOOL ImpersonateClient(void);
+
+// event logging
+static VOID LogTimingEvent(DWORD dwEventID, LPTSTR lpString1, DWORD dwTime);
+
+#endif // _AFSD_FLUSHVOL_H_
+
#include "smb.h"
#include "cm_rpc.h"
+#include "lanahelper.h"
-extern int RXAFSCB_ExecuteRequest();
-extern int RXSTATS_ExecuteRequest();
+extern int RXAFSCB_ExecuteRequest(struct rx_call *z_call);
+extern int RXSTATS_ExecuteRequest(struct rx_call *z_call);
extern afs_int32 cryptall;
sprintf(u, "%s: %s\n", t, s);
if (afsi_file != INVALID_HANDLE_VALUE)
WriteFile(afsi_file, u, strlen(u), &zilch, NULL);
+#ifdef NOTSERVICE
+ printf("%s", u);
+#endif
} else {
if (afsi_file != INVALID_HANDLE_VALUE)
WriteFile(afsi_file, s, strlen(s), &zilch, NULL);
long stats;
long traceBufSize;
long ltt, ltto;
+ long rx_mtu, rx_nojumbo;
char rootCellName[256];
struct rx_service *serverp;
static struct rx_securityClass *nullServerSecurityClassp;
dummyLen = sizeof(LANadapter);
code = RegQueryValueEx(parmKey, "LANadapter", NULL, NULL,
(BYTE *) &LANadapter, &dummyLen);
- if (code == ERROR_SUCCESS)
+ if (code == ERROR_SUCCESS) {
afsi_log("LAN adapter number %d", LANadapter);
- else {
+ if (LANadapter < 0 || LANadapter > MAX_LANA)
+ LANadapter = -1;
+ } else {
LANadapter = -1;
+ }
+ if ( LANadapter == -1 )
afsi_log("Default LAN adapter number");
- }
dummyLen = sizeof(cacheSize);
code = RegQueryValueEx(parmKey, "CacheSize", NULL, NULL,
cm_NetBiosName[0] = 0; /* default off */
}
+ dummyLen = sizeof(smb_hideDotFiles);
+ code = RegQueryValueEx(parmKey, "HideDotFiles", NULL, NULL,
+ (BYTE *) &smb_hideDotFiles, &dummyLen);
+ if (code != ERROR_SUCCESS) {
+ smb_hideDotFiles = 1; /* default on */
+ }
+ afsi_log("Dot files/dirs will %sbe marked hidden",
+ smb_hideDotFiles ? "" : "not ");
+
+ dummyLen = sizeof(smb_maxMpxRequests);
+ code = RegQueryValueEx(parmKey, "MaxMpxRequests", NULL, NULL,
+ (BYTE *) &smb_maxMpxRequests, &dummyLen);
+ if (code != ERROR_SUCCESS) {
+ smb_maxMpxRequests = 50;
+ }
+ afsi_log("Maximum number of multiplexed sessions is %d", smb_maxMpxRequests);
+
+ dummyLen = sizeof(smb_maxVCPerServer);
+ code = RegQueryValueEx(parmKey, "MaxVCPerServer", NULL, NULL,
+ (BYTE *) &smb_maxVCPerServer, &dummyLen);
+ if (code != ERROR_SUCCESS) {
+ smb_maxVCPerServer = 100;
+ }
+ afsi_log("Maximum number of VCs per server is %d", smb_maxVCPerServer);
+
+ dummyLen = sizeof(rx_nojumbo);
+ code = RegQueryValueEx(parmKey, "RxNoJumbo", NULL, NULL,
+ (BYTE *) &rx_nojumbo, &dummyLen);
+ if (code != ERROR_SUCCESS) {
+ rx_nojumbo = 0;
+ }
+ if(rx_nojumbo)
+ afsi_log("RX Jumbograms are disabled");
+
+ dummyLen = sizeof(rx_mtu);
+ code = RegQueryValueEx(parmKey, "RxMaxMTU", NULL, NULL,
+ (BYTE *) &rx_mtu, &dummyLen);
+ if (code != ERROR_SUCCESS || !rx_mtu) {
+ rx_mtu = -1;
+ }
+ if(rx_mtu != -1)
+ afsi_log("RX maximum MTU is %d", rx_mtu);
+
RegCloseKey (parmKey);
/* setup early variables */
/* These both used to be configurable. */
smb_UseV3 = 1;
- buf_bufferSize = CM_CONFIGDEFAULT_BLOCKSIZE;
+ buf_bufferSize = CM_CONFIGDEFAULT_BLOCKSIZE;
/* turn from 1024 byte units into memory blocks */
- cacheBlocks = (cacheSize * 1024) / buf_bufferSize;
+ cacheBlocks = (cacheSize * 1024) / buf_bufferSize;
/* setup and enable debug log */
afsd_logp = osi_LogCreate("afsd", traceBufSize);
afsi_log("osi_LogCreate log addr %x", (int)afsd_logp);
- osi_LogEnable(afsd_logp);
+ osi_LogEnable(afsd_logp);
logReady = 1;
+ osi_Log0(afsd_logp, "Log init");
+
/* get network related info */
cm_noIPAddr = CM_MAXINTERFACE_ADDR;
code = syscfg_GetIFInfo(&cm_noIPAddr,
- cm_IPAddr, cm_SubnetMask,
- cm_NetMtu, cm_NetFlags);
+ cm_IPAddr, cm_SubnetMask,
+ cm_NetMtu, cm_NetFlags);
if ( (cm_noIPAddr <= 0) || (code <= 0 ) )
afsi_log("syscfg_GetIFInfo error code %d", code);
else
afsi_log("First Network address %x SubnetMask %x",
- cm_IPAddr[0], cm_SubnetMask[0]);
+ cm_IPAddr[0], cm_SubnetMask[0]);
/*
* Save client configuration for GetCacheConfig requests
cm_initParams.setTime = 0;
cm_initParams.memCache = 0;
+ /* Set RX parameters before initializing RX */
+ if ( rx_nojumbo )
+ rx_SetNoJumbo();
+
+ if ( rx_mtu != -1 )
+ rx_SetMaxMTU(rx_mtu);
+
/* initialize RX, and tell it to listen to port 7001, which is used for
- * callback RPC messages.
- */
+ * callback RPC messages.
+ */
code = rx_Init(htons(7001));
afsi_log("rx_Init code %x", code);
if (code != 0) {
/* create an unauthenticated service #1 for callbacks */
nullServerSecurityClassp = rxnull_NewServerSecurityObject();
- serverp = rx_NewService(0, 1, "AFS", &nullServerSecurityClassp, 1,
- RXAFSCB_ExecuteRequest);
+ serverp = rx_NewService(0, 1, "AFS", &nullServerSecurityClassp, 1,
+ RXAFSCB_ExecuteRequest);
afsi_log("rx_NewService addr %x", (int)serverp);
if (serverp == NULL) {
*reasonP = "unknown error";
}
nullServerSecurityClassp = rxnull_NewServerSecurityObject();
- serverp = rx_NewService(0, RX_STATS_SERVICE_ID, "rpcstats",
- &nullServerSecurityClassp, 1, RXSTATS_ExecuteRequest);
+ serverp = rx_NewService(0, RX_STATS_SERVICE_ID, "rpcstats",
+ &nullServerSecurityClassp, 1, RXSTATS_ExecuteRequest);
afsi_log("rx_NewService addr %x", (int)serverp);
if (serverp == NULL) {
*reasonP = "unknown error";
return -1;
}
- /* start server threads, *not* donating this one to the pool */
- rx_StartServer(0);
+ /* start server threads, *not* donating this one to the pool */
+ rx_StartServer(0);
afsi_log("rx_StartServer");
/* init user daemon, and other packages */
cm_InitConn();
- cm_InitCell();
-
- cm_InitServer();
+ cm_InitCell();
- cm_InitVolume();
+ cm_InitServer();
- cm_InitIoctl();
+ cm_InitVolume();
+
+ cm_InitIoctl();
- smb_InitIoctl();
+ smb_InitIoctl();
- cm_InitCallback();
+ cm_InitCallback();
- cm_InitSCache(stats);
+ cm_InitSCache(stats);
- code = cm_InitDCache(0, cacheBlocks);
+ code = cm_InitDCache(0, cacheBlocks);
afsi_log("cm_InitDCache code %x", code);
if (code != 0) {
*reasonP = "error initializing cache";
}
#ifdef AFS_AFSDB_ENV
+#if !defined(_WIN32_WINNT) || _WIN32_WINNT < 0x500
if (cm_InitDNS(cm_dnsEnabled) == -1)
cm_dnsEnabled = 0; /* init failed, so deactivate */
afsi_log("cm_InitDNS %d", cm_dnsEnabled);
#endif
+#endif
code = cm_GetRootCellName(rootCellName);
- afsi_log("cm_GetRootCellName code %d rcn %s", code,
- (code ? "<none>" : rootCellName));
- if (code != 0 && !cm_freelanceEnabled) {
+ afsi_log("cm_GetRootCellName code %d, cm_freelanceEnabled= %d, rcn= %s",
+ code, cm_freelanceEnabled, (code ? "<none>" : rootCellName));
+ if (code != 0 && !cm_freelanceEnabled)
+ {
*reasonP = "can't find root cell name in afsd.ini";
return -1;
+ }
+ else if (cm_freelanceEnabled)
+ cm_rootCellp = NULL;
+
+ if (code == 0 && !cm_freelanceEnabled)
+ {
+ cm_rootCellp = cm_GetCell(rootCellName, CM_FLAG_CREATE);
+ afsi_log("cm_GetCell addr %x", (int)cm_rootCellp);
+ if (cm_rootCellp == NULL)
+ {
+ *reasonP = "can't find root cell in afsdcell.ini";
+ return -1;
}
- else if (cm_freelanceEnabled)
- cm_rootCellp = NULL;
-
- if (code == 0 && !cm_freelanceEnabled) {
- cm_rootCellp = cm_GetCell(rootCellName, CM_FLAG_CREATE);
- afsi_log("cm_GetCell addr %x", (int)cm_rootCellp);
- if (cm_rootCellp == NULL) {
- *reasonP = "can't find root cell in afsdcell.ini";
- return -1;
- }
}
#ifdef AFS_FREELANCE_CLIENT
/* this should really be in an init daemon from here on down */
- if (!cm_freelanceEnabled) {
- code = cm_GetVolumeByName(cm_rootCellp, cm_rootVolumeName, cm_rootUserp,
- &req, CM_FLAG_CREATE, &cm_rootVolumep);
- afsi_log("cm_GetVolumeByName code %x root vol %x", code,
- (code ? (cm_volume_t *)-1 : cm_rootVolumep));
- if (code != 0) {
+ if (!cm_freelanceEnabled) {
+ code = cm_GetVolumeByName(cm_rootCellp, cm_rootVolumeName, cm_rootUserp,
+ &req, CM_FLAG_CREATE, &cm_rootVolumep);
+ afsi_log("cm_GetVolumeByName code %x root vol %x", code,
+ (code ? (cm_volume_t *)-1 : cm_rootVolumep));
+ if (code != 0) {
*reasonP = "can't find root volume in root cell";
return -1;
- }
}
+ }
/* compute the root fid */
if (!cm_freelanceEnabled) {
- cm_rootFid.cell = cm_rootCellp->cellID;
- cm_rootFid.volume = cm_GetROVolumeID(cm_rootVolumep);
- cm_rootFid.vnode = 1;
- cm_rootFid.unique = 1;
+ cm_rootFid.cell = cm_rootCellp->cellID;
+ cm_rootFid.volume = cm_GetROVolumeID(cm_rootVolumep);
+ cm_rootFid.vnode = 1;
+ cm_rootFid.unique = 1;
}
else
- cm_FakeRootFid(&cm_rootFid);
+ cm_FakeRootFid(&cm_rootFid);
- code = cm_GetSCache(&cm_rootFid, &cm_rootSCachep, cm_rootUserp, &req);
+ code = cm_GetSCache(&cm_rootFid, &cm_rootSCachep, cm_rootUserp, &req);
afsi_log("cm_GetSCache code %x scache %x", code,
- (code ? (cm_scache_t *)-1 : cm_rootSCachep));
+ (code ? (cm_scache_t *)-1 : cm_rootSCachep));
if (code != 0) {
*reasonP = "unknown error";
return -1;
{
char hostName[200];
char *ctemp;
+ lana_number_t lana;
/* Do this last so that we don't handle requests before init is done.
* Here we initialize the SMB listener.
*/
- if (!cm_NetBiosName[0])
- {
- strcpy(hostName, cm_HostName);
- ctemp = strchr(hostName, '.'); /* turn ntdfs.* into ntdfs */
- if (ctemp) *ctemp = 0;
+ if (LANadapter == -1) {
+ /* Find the default LAN adapter to use. First look for
+ * the adapter named AFS; otherwise, unless we are doing
+ * gateway service, look for any valid loopback adapter.
+ */
+ lana = lana_FindLanaByName("AFS");
+ if (lana == LANA_INVALID && !isGateway)
+ lana = lana_FindLoopback();
+ if (lana != LANA_INVALID)
+ LANadapter = lana;
+ }
+ afsi_log("Lana %d", (int) lana);
+ /* If we are using a loopback adapter, we can use the preferred
+ * (but non-unique) server name; otherwise, we must fall back to
+ * the <machine>-AFS name.
+ */
+ if (LANadapter >= 0 && lana_IsLoopback((lana_number_t) LANadapter)) {
+ if ( cm_NetBiosName[0] )
+ strcpy(hostName, cm_NetBiosName);
+ else
+ strcpy(hostName, "AFS");
+ } else {
+ if (!cm_NetBiosName[0])
+ {
+ strcpy(hostName, cm_HostName);
+ ctemp = strchr(hostName, '.'); /* turn ntdfs.* into ntdfs */
+ if (ctemp) *ctemp = 0;
hostName[11] = 0; /* ensure that even after adding the -A, we
* leave one byte free for the netbios server
* type.
*/
- strcat(hostName, "-AFS");
- } else {
- strcpy(hostName, cm_NetBiosName);
+ strcat(hostName, "-AFS");
+ } else {
+ strcpy(hostName, cm_NetBiosName);
+ }
+ _strupr(hostName);
}
- _strupr(hostName);
-
- smb_Init(afsd_logp, hostName, smb_UseV3, LANadapter, numSvThreads,
- aMBfunc);
+ smb_Init(afsd_logp, hostName, smb_UseV3, LANadapter, numSvThreads, aMBfunc);
afsi_log("smb_Init");
return 0;
#include <crtdbg.h>
#endif
+/*
+// The following is defined if you want to receive Power notifications,
+// including Hibernation, and also subsequent flushing of AFS volumes
+//
+// #define REGISTER_POWER_NOTIFICATIONS
+//
+// Check
+*/
+#include "afsd_flushvol.h"
+
extern void afsi_log(char *pattern, ...);
HANDLE WaitToTerminate;
static SERVICE_STATUS ServiceStatus;
static SERVICE_STATUS_HANDLE StatusHandle;
-void afsd_ServiceControlHandler(DWORD ctrlCode)
+DWORD
+afsd_ServiceFlushVolume(DWORD dwlpEventData)
+{
+ DWORD dwRet = ERROR_NETWORK_BUSY; /* or NO_ERROR */
+
+ /*
+ ** If UI bit is not set, user interaction is not possible
+ ** BUT, since we are a NON-interactive service, and therefore
+ ** have NO user I/O, it doesn't much matter.
+ ** This benign code left here as example of how to find this out
+ */
+ BOOL bUI = (dwlpEventData & 1);
+
+ /* flush volume */
+ if ( PowerNotificationThreadNotify() )
+ {
+ dwRet = NO_ERROR;
+ }
+
+ else
+ {
+ /* flush was unsuccessful, or timeout - deny shutdown */
+ dwRet = ERROR_NETWORK_BUSY;
+ }
+
+ /* to deny hibernate, simply return
+ // any value besides NO_ERROR.
+ // For example:
+ // dwRet = ERROR_NETWORK_BUSY;
+ */
+
+ return dwRet;
+}
+
+/*
+** Extended ServiceControlHandler that provides Event types
+** for monitoring Power events, for example.
+*/
+DWORD
+afsd_ServiceControlHandlerEx(
+ DWORD ctrlCode,
+ DWORD dwEventType,
+ LPVOID lpEventData,
+ LPVOID lpContext
+ )
{
HKEY parmKey;
DWORD dummyLen, doTrace;
long code;
+ DWORD dwRet = ERROR_CALL_NOT_IMPLEMENTED;
+
+ switch (ctrlCode)
+ {
+ case SERVICE_CONTROL_STOP:
+ /* Shutdown RPC */
+ RpcMgmtStopServerListening(NULL);
+
+ /* Force trace if requested */
+ code = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
+ AFSConfigKeyName,
+ 0, KEY_QUERY_VALUE, &parmKey);
+ if (code != ERROR_SUCCESS)
+ goto doneTrace;
+
+ dummyLen = sizeof(doTrace);
+ code = RegQueryValueEx(parmKey, "TraceOnShutdown",
+ NULL, NULL,
+ (BYTE *) &doTrace, &dummyLen);
+ RegCloseKey (parmKey);
+ if (code != ERROR_SUCCESS)
+ doTrace = 0;
+ if (doTrace)
+ afsd_ForceTrace(FALSE);
+
+ doneTrace:
+ ServiceStatus.dwCurrentState = SERVICE_STOP_PENDING;
+ ServiceStatus.dwWin32ExitCode = NO_ERROR;
+ ServiceStatus.dwCheckPoint = 1;
+ ServiceStatus.dwWaitHint = 10000;
+ ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_POWEREVENT;
+ SetServiceStatus(StatusHandle, &ServiceStatus);
+ SetEvent(WaitToTerminate);
+ dwRet = NO_ERROR;
+ break;
+
+ case SERVICE_CONTROL_INTERROGATE:
+ ServiceStatus.dwCurrentState = SERVICE_RUNNING;
+ ServiceStatus.dwWin32ExitCode = NO_ERROR;
+ ServiceStatus.dwCheckPoint = 0;
+ ServiceStatus.dwWaitHint = 0;
+ ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_POWEREVENT;
+ SetServiceStatus(StatusHandle, &ServiceStatus);
+ dwRet = NO_ERROR;
+ break;
- switch (ctrlCode) {
- case SERVICE_CONTROL_STOP:
- /* Shutdown RPC */
- RpcMgmtStopServerListening(NULL);
-
- /* Force trace if requested */
- code = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
- AFSConfigKeyName,
- 0, KEY_QUERY_VALUE, &parmKey);
- if (code != ERROR_SUCCESS)
- goto doneTrace;
-
- dummyLen = sizeof(doTrace);
- code = RegQueryValueEx(parmKey, "TraceOnShutdown",
- NULL, NULL,
- (BYTE *) &doTrace, &dummyLen);
- RegCloseKey (parmKey);
- if (code != ERROR_SUCCESS)
- doTrace = 0;
- if (doTrace)
- afsd_ForceTrace(FALSE);
-
-doneTrace:
- ServiceStatus.dwCurrentState = SERVICE_STOP_PENDING;
- ServiceStatus.dwWin32ExitCode = NO_ERROR;
- ServiceStatus.dwCheckPoint = 1;
- ServiceStatus.dwWaitHint = 10000;
- ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
- SetServiceStatus(StatusHandle, &ServiceStatus);
- SetEvent(WaitToTerminate);
- break;
- case SERVICE_CONTROL_INTERROGATE:
- ServiceStatus.dwCurrentState = SERVICE_RUNNING;
- ServiceStatus.dwWin32ExitCode = NO_ERROR;
- ServiceStatus.dwCheckPoint = 0;
- ServiceStatus.dwWaitHint = 0;
- ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
- SetServiceStatus(StatusHandle, &ServiceStatus);
- break;
/* XXX handle system shutdown */
/* XXX handle pause & continue */
- }
+ case SERVICE_CONTROL_POWEREVENT:
+ {
+ /*
+ ** dwEventType of this notification == WPARAM of WM_POWERBROADCAST
+ ** Return NO_ERROR == return TRUE for that message, i.e. accept request
+ ** Return any error code to deny request,
+ ** i.e. as if returning BROADCAST_QUERY_DENY
+ */
+ switch((int) dwEventType)
+ {
+ case PBT_APMQUERYSUSPEND:
+ case PBT_APMQUERYSTANDBY:
+
+#ifdef REGISTER_POWER_NOTIFICATIONS
+ /* handle event */
+ dwRet = afsd_ServiceFlushVolume((DWORD) lpEventData);
+#else
+ dwRet = NO_ERROR;
+#endif
+ break;
+
+ /* allow remaining case PBT_WhatEver */
+ case PBT_APMSUSPEND:
+ case PBT_APMSTANDBY:
+ case PBT_APMRESUMECRITICAL:
+ case PBT_APMRESUMESUSPEND:
+ case PBT_APMRESUMESTANDBY:
+ case PBT_APMBATTERYLOW:
+ case PBT_APMPOWERSTATUSCHANGE:
+ case PBT_APMOEMEVENT:
+ case PBT_APMRESUMEAUTOMATIC:
+ default:
+ dwRet = NO_ERROR;
+ }
+ }
+ } /* end switch(ctrlCode) */
+ return dwRet;
}
#if 1
#define AFSD_INIT_HOOK "AfsdInitHook"
#define AFSD_HOOK_DLL "afsdhook.dll"
-void afsd_Main()
+void afsd_Main(DWORD argc, LPTSTR *argv)
{
long code;
char *reason;
WaitToTerminate = CreateEvent(NULL, TRUE, FALSE, NULL);
#ifndef NOTSERVICE
- StatusHandle = RegisterServiceCtrlHandler(AFS_DAEMON_SERVICE_NAME,
- (LPHANDLER_FUNCTION) afsd_ServiceControlHandler);
+ StatusHandle = RegisterServiceCtrlHandlerEx(AFS_DAEMON_SERVICE_NAME,
+ (LPHANDLER_FUNCTION_EX) afsd_ServiceControlHandlerEx,
+ NULL /* user context */
+ );
ServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
ServiceStatus.dwServiceSpecificExitCode = 0;
ServiceStatus.dwCurrentState = SERVICE_START_PENDING;
ServiceStatus.dwWin32ExitCode = NO_ERROR;
ServiceStatus.dwCheckPoint = 1;
- ServiceStatus.dwWaitHint = 15000;
- ServiceStatus.dwControlsAccepted = 0;
+ ServiceStatus.dwWaitHint = 30000;
+ /* accept Power Events */
+ ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_POWEREVENT;
SetServiceStatus(StatusHandle, &ServiceStatus);
#endif
+
{
HANDLE h; char *ptbuf[1];
h = RegisterEventSource(NULL, AFS_DAEMON_EVENT_NAME);
DeregisterEventSource(h);
}
+#ifdef REGISTER_POWER_NOTIFICATIONS
+ /* create thread used to flush cache */
+ PowerNotificationThreadCreate();
+#endif
+
afsi_start();
/* allow an exit to be called prior to any initialization */
if (code != 0)
osi_panic(reason, __FILE__, __LINE__);
+#ifndef NOTSERVICE
+ ServiceStatus.dwCheckPoint++;
+ ServiceStatus.dwWaitHint -= 5000;
+ SetServiceStatus(StatusHandle, &ServiceStatus);
+#endif
code = afsd_InitDaemons(&reason);
if (code != 0)
osi_panic(reason, __FILE__, __LINE__);
+#ifndef NOTSERVICE
+ ServiceStatus.dwCheckPoint++;
+ ServiceStatus.dwWaitHint -= 5000;
+ SetServiceStatus(StatusHandle, &ServiceStatus);
+#endif
code = afsd_InitSMB(&reason, DummyMessageBox);
if (code != 0)
osi_panic(reason, __FILE__, __LINE__);
ServiceStatus.dwWin32ExitCode = NO_ERROR;
ServiceStatus.dwCheckPoint = 0;
ServiceStatus.dwWaitHint = 0;
- ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
+
+ /* accept Power events */
+ ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_POWEREVENT;
SetServiceStatus(StatusHandle, &ServiceStatus);
#endif
{
ServiceStatus.dwCheckPoint = 0;
ServiceStatus.dwWaitHint = 0;
ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
+
+ /* also now accept Power events - shutdown maybe? */
+ ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
+
+#ifdef REGISTER_POWER_NOTIFICATIONS
+ /* terminate thread used to flush cache */
+ PowerNotificationThreadExit();
+#endif
+
SetServiceStatus(StatusHandle, &ServiceStatus);
}
DWORD __stdcall afsdMain_thread(void* notUsed)
{
- afsd_Main();
+ afsd_Main(0, (LPTSTR*)NULL);
return(0);
}
/* from .xg file */
/* FIXME: these were "long" but Windows NT wants "int" */
-int VL_GetEntryByID(struct rx_connection *, long, long, struct vldbentry *);
+int VL_GetEntryByID(struct rx_connection *, afs_int32, afs_int32, struct vldbentry *);
int VL_GetEntryByNameO(struct rx_connection *, char *, struct vldbentry *);
int VL_ProbeServer(struct rx_connection *);
-int VL_GetEntryBYIDN(struct rx_connection *, long, long, struct nvldbentry *);
+int VL_GetEntryBYIDN(struct rx_connection *, afs_int32, afs_int32, struct nvldbentry *);
int VL_GetEntryByNameN(struct rx_connection *, char *, struct nvldbentry *);
/* from .xg file */
int StartRXAFS_StoreData (struct rx_call *,
struct AFSFid *Fid,
struct AFSStoreStatus *InStatus,
- afs_int32 Pos,
- afs_int32 Length,
- afs_int32 FileLength);
+ afs_uint32 Pos,
+ afs_uint32 Length,
+ afs_uint32 FileLength);
int EndRXAFS_StoreData(struct rx_call *,
struct AFSFetchStatus *OutStatus,
memset(cp, 0, sizeof(*cp));
code = cm_SearchCellFile(namep, fullname, cm_AddCellProc, cp);
if (code) {
+ afsi_log("in cm_GetCell_gen code= %d fullname= %s", code, fullname);
+
#ifdef AFS_AFSDB_ENV
if (cm_dnsEnabled /*&& cm_DomainValid(namep)*/)
code = cm_SearchCellByDNS(namep, fullname, &ttl, cm_AddCellProc, cp);
#include "cm_config.h"
#ifdef AFS_AFSDB_ENV
+#if !defined(DJGPP) && defined(_WIN32_WINNT) && _WIN32_WINNT >= 0x500
+#include <windns.h>
+#define DNSAPI_ENV
+#else
#include "cm_dns.h"
+#endif
#include <afs/afsint.h>
#endif
char AFSConfigKeyName[] =
"SYSTEM\\CurrentControlSet\\Services\\TransarcAFSDaemon\\Parameters";
+/* TODO: these should be pulled in from dirpath.h */
#define AFS_THISCELL "ThisCell"
#define AFS_CELLSERVDB_UNIX "CellServDB"
#define AFS_CELLSERVDB_NT "afsdcell.ini"
#define AFS_CELLSERVDB AFS_CELLSERVDB_NT
#endif /* DJGPP || WIN95 */
+DWORD TraceOption=1;
+
+#define TRACE_OPTION_EVENT 1
+#define ISLOGONTRACE(v) ( ((v) & TRACE_OPTION_EVENT)==TRACE_OPTION_EVENT)
+
+void DebugEvent0_local(char *a)
+{
+ HANDLE h; char *ptbuf[1];
+ if (!ISLOGONTRACE(TraceOption))
+ return;
+ h = RegisterEventSource(NULL, a);
+ ptbuf[0] = a;
+ ReportEvent(h, EVENTLOG_INFORMATION_TYPE, 0, 0, NULL, 1, 0, (const char **)ptbuf, NULL);
+ DeregisterEventSource(h);
+}
+
+#define MAXBUF_ 131
+
+void DebugEvent_local(char *a,char *b,...)
+{
+ HANDLE h; char *ptbuf[1],buf[MAXBUF_+1];
+ va_list marker;
+ if (!ISLOGONTRACE(TraceOption))
+ return;
+ h = RegisterEventSource(NULL, a);
+ va_start(marker,b);
+ _vsnprintf(buf,MAXBUF_,b,marker);
+ ptbuf[0] = buf;
+ ReportEvent(h, EVENTLOG_INFORMATION_TYPE, 0, 0, NULL, 1, 0, (const char **)ptbuf, NULL);\
+ DeregisterEventSource(h);
+ va_end(marker);
+}
static long cm_ParsePair(char *lineBufferp, char *leftp, char *rightp)
{
long ip_addr;
int c1, c2, c3, c4;
char aname[256];
-#endif
char *afsconf_path;
+#endif
foundCell = 0;
tfilep = fopen(wdir, "r");
+#if defined(DJGPP) || defined(AFS_WIN95_ENV)
if (!tfilep) {
/* If we are using DJGPP client, cellservdb will be in afsconf dir. */
/* If we are in Win95 here, we are linking with klog etc. and are
tfilep = fopen(wdir, "r");
if (!tfilep) return -2;
}
+#else
+ /* If we are NT or higher, we don't do DJGPP, So just fail */
+ if ( !tfilep )
+ return -2;
+#endif
bestp = fopen(wdir, "r");
-
+
+ DebugEvent_local("AFS- cm_searchfile fopen", "Handle[%x], wdir[%s]", bestp, wdir);
+
/* have we seen the cell line for the guy we're looking for? */
inRightCell = 0;
while (1) {
strcpy(newCellNamep, lineBuffer+1);
inRightCell = 1;
tracking = 0;
+ DebugEvent_local("AFS- cm_searchfile is cell", "inRightCell[%x], linebuffer[%s]",
+ inRightCell, lineBuffer);
}
else if (strnicmp(lineBuffer+1, cellNamep,
strlen(cellNamep)) == 0) {
if (inRightCell) {
#if !defined(DJGPP) && !defined(AFS_WIN95_ENV)
/* add the server to the VLDB list */
+ WSASetLastError(0);
thp = gethostbyname(valuep);
+ {
+ int iErr = 0;
+ iErr = WSAGetLastError();
+ DebugEvent_local("AFS- cm_searchfile inRightCell",
+ "thp[%x], valuep[%s], WSAGetLastError[%d]",
+ thp, valuep, iErr);
+ }
if (thp) {
memcpy(&vlSockAddr.sin_addr.s_addr, thp->h_addr,
sizeof(long));
cm_configProc_t *procp, void *rockp)
{
#ifdef AFS_AFSDB_ENV
- int rc;
- int cellHosts[AFSMAXCELLHOSTS];
- int numServers;
- int i;
- struct sockaddr_in vlSockAddr;
-
- rc = getAFSServer(cellNamep, cellHosts, &numServers, ttl);
- if (rc == 0 && numServers > 0) { /* found the cell */
- for (i = 0; i < numServers; i++) {
- memcpy(&vlSockAddr.sin_addr.s_addr, &cellHosts[i],
- sizeof(long));
+#ifndef DNSAPI_ENV
+ int rc;
+ int cellHosts[AFSMAXCELLHOSTS];
+ int numServers;
+ int i;
+ struct sockaddr_in vlSockAddr;
+
+ DebugEvent_local("AFS SearchCellDNS-","Doing search for [%s]", cellNamep);
+ rc = getAFSServer(cellNamep, cellHosts, &numServers, ttl);
+ if (rc == 0 && numServers > 0) { /* found the cell */
+ for (i = 0; i < numServers; i++) {
+ memcpy(&vlSockAddr.sin_addr.s_addr, &cellHosts[i],
+ sizeof(long));
vlSockAddr.sin_family = AF_INET;
/* sin_port supplied by connection code */
if (procp)
(*procp)(rockp, &vlSockAddr, NULL);
if(newCellNamep)
strcpy(newCellNamep,cellNamep);
- }
- return 0; /* found cell */
- }
- else
-#endif /* AFS_AFSDB_ENV */
+ }
+ return 0; /* found cell */
+ }
+ else
return -1; /* not found */
+#else /* DNSAPI_ENV */
+ PDNS_RECORD pDnsCell, pDnsIter, pDnsVol,pDnsVolIter, pDnsCIter;
+ LPSTR vlServers[AFSMAXCELLHOSTS];
+ IP4_ADDRESS vlAddrs[AFSMAXCELLHOSTS];
+ WORD nvlServers;
+ DWORD wttl, i;
+ BOOL success;
+ struct sockaddr_in vlSockAddr;
+
+ success = FALSE;
+
+ /* query the AFSDB records of cell */
+ if(DnsQuery_A(cellNamep, DNS_TYPE_AFSDB, DNS_QUERY_STANDARD, NULL, &pDnsCell, NULL) == ERROR_SUCCESS) {
+
+ memset((void*) &vlSockAddr, 0, sizeof(vlSockAddr));
+
+ nvlServers = 0; wttl = 0;
+
+ /* go through the returned records */
+ for(pDnsIter = pDnsCell;pDnsIter; pDnsIter = pDnsIter->pNext) {
+ /* if we find an AFSDB record with Preference set to 1, we found a volserver */
+ if(pDnsIter->wType == DNS_TYPE_AFSDB && pDnsIter->Data.Afsdb.wPreference == 1) {
+ vlServers[nvlServers++] = pDnsIter->Data.Afsdb.pNameExchange;
+ if(!wttl) wttl = pDnsIter->dwTtl;
+ if(nvlServers == AFSMAXCELLHOSTS) break;
+ }
+ }
+
+ for(i=0;i<nvlServers;i++) vlAddrs[i] = 0;
+
+ /* now check if there are any A records in the results */
+ for(pDnsIter = pDnsCell; pDnsIter; pDnsIter = pDnsIter->pNext) {
+ if(pDnsIter->wType == DNS_TYPE_A)
+ /* check if its for one of the volservers */
+ for(i=0;i<nvlServers;i++)
+ if(stricmp(pDnsIter->pName, vlServers[i]) == 0)
+ vlAddrs[i] = pDnsIter->Data.A.IpAddress;
+ }
+
+ for(i=0;i<nvlServers;i++) {
+ /* if we don't have an IP yet, then we should try resolving the volserver hostname
+ in a separate query. */
+ if(!vlAddrs[i]) {
+ if(DnsQuery_A(vlServers[i], DNS_TYPE_A, DNS_QUERY_STANDARD, NULL, &pDnsVol, NULL) == ERROR_SUCCESS) {
+ for(pDnsVolIter = pDnsVol; pDnsVolIter; pDnsVolIter=pDnsVolIter->pNext) {
+ /* if we get an A record, keep it */
+ if(pDnsVolIter->wType == DNS_TYPE_A && stricmp(vlServers[i], pDnsVolIter->pName)==0) {
+ vlAddrs[i] = pDnsVolIter->Data.A.IpAddress;
+ break;
+ }
+ /* if we get a CNAME, look for a corresponding A record */
+ if(pDnsVolIter->wType == DNS_TYPE_CNAME && stricmp(vlServers[i], pDnsVolIter->pName)==0) {
+ for(pDnsCIter=pDnsVolIter; pDnsCIter; pDnsCIter=pDnsCIter->pNext) {
+ if(pDnsCIter->wType == DNS_TYPE_A && stricmp(pDnsVolIter->Data.CNAME.pNameHost, pDnsCIter->pName)==0) {
+ vlAddrs[i] = pDnsCIter->Data.A.IpAddress;
+ break;
+ }
+ }
+ if(vlAddrs[i]) break;
+ /* TODO: if the additional section is missing, then do another lookup for the CNAME */
+ }
+ }
+ /* we are done with the volserver lookup */
+ DnsRecordListFree(pDnsVol, DnsFreeRecordListDeep);
+ }
+ }
+
+ /* if we found a volserver, then add it */
+ if(vlAddrs[i]) {
+ vlSockAddr.sin_family = AF_INET;
+ vlSockAddr.sin_addr.s_addr = vlAddrs[i];
+ if(procp)
+ (*procp)(rockp, &vlSockAddr, vlServers[i]);
+ success = TRUE;
+ }
+ }
+
+ DnsRecordListFree(pDnsCell, DnsFreeRecordListDeep);
+ }
+
+ if(!success) return -1;
+ else {
+ strcpy(newCellNamep, cellNamep);
+ if(ttl) *ttl = (int) wttl;
+ return 0;
+ }
+
+#endif /* DNSAPI_ENV */
+#else
+ return -1; /* not found */
+#endif /* AFS_AFSDB_ENV */
}
#if !defined(DJGPP) && !defined(AFS_WIN95_ENV)
*
* volSyncp and/or cbrp may also be NULL.
*/
+int
cm_Analyze(cm_conn_t *connp, cm_user_t *userp, cm_req_t *reqp,
struct cm_fid *fidp,
AFSVolSync *volSyncp, cm_callbackRequest_t *cbrp, long errorCode)
cm_HoldSCache(tscp);
symlinkCount = 0;
while (1) {
- tc = *tp++;
+ tc = *tp++;
- /* map Unix slashes into DOS ones so we can interpret Unix
- * symlinks properly
- */
- if (tc == '/') tc = '\\';
-
- if (!haveComponent) {
+ /* map Unix slashes into DOS ones so we can interpret Unix
+ * symlinks properly
+ */
+ if (tc == '/') tc = '\\';
+
+ if (!haveComponent) {
if (tc == '\\') continue;
- else if (tc == 0) {
+ else if (tc == 0) {
if (phase == 1) {
phase = 2;
tp = pathp;
continue;
}
- code = 0;
- break;
- }
- else {
+ code = 0;
+ break;
+ }
+ else {
haveComponent = 1;
- cp = component;
- *cp++ = tc;
+ cp = component;
+ *cp++ = tc;
+ }
+ }
+ else {
+ /* we have a component here */
+ if (tc == 0 || tc == '\\') {
+ /* end of the component; we're at the last
+ * component if tc == 0. However, if the last
+ * is a symlink, we have more to do.
+ */
+ *cp++ = 0; /* add null termination */
+ extraFlag = 0;
+ if ((flags & CM_FLAG_DIRSEARCH) && tc == 0)
+ extraFlag = CM_FLAG_NOMOUNTCHASE;
+ code = cm_Lookup(tscp, component,
+ flags | extraFlag,
+ userp, reqp, &nscp);
+
+ if (code) {
+ cm_ReleaseSCache(tscp);
+ if (psp) cm_FreeSpace(psp);
+ return code;
+ }
+ haveComponent = 0; /* component done */
+ dirScp = tscp; /* for some symlinks */
+ tscp = nscp; /* already held */
+ if (tc == 0 && !(flags & CM_FLAG_FOLLOW) && phase == 2) {
+ code = 0;
+ cm_ReleaseSCache(dirScp);
+ break;
+ }
+
+ /* now, if tscp is a symlink, we should follow
+ * it and assemble the path again.
+ */
+ lock_ObtainMutex(&tscp->mx);
+ code = cm_SyncOp(tscp, NULL, userp, reqp, 0,
+ CM_SCACHESYNC_GETSTATUS
+ | CM_SCACHESYNC_NEEDCALLBACK);
+ if (code) {
+ lock_ReleaseMutex(&tscp->mx);
+ cm_ReleaseSCache(tscp);
+ cm_ReleaseSCache(dirScp);
+ break;
+ }
+ if (tscp->fileType == CM_SCACHETYPE_SYMLINK) {
+ /* this is a symlink; assemble a new buffer */
+ lock_ReleaseMutex(&tscp->mx);
+ if (symlinkCount++ >= 16) {
+ cm_ReleaseSCache(tscp);
+ cm_ReleaseSCache(dirScp);
+ if (psp) cm_FreeSpace(psp);
+ return CM_ERROR_TOOBIG;
}
- }
- else {
- /* we have a component here */
- if (tc == 0 || tc == '\\') {
- /* end of the component; we're at the last
- * component if tc == 0. However, if the last
- * is a symlink, we have more to do.
- */
- *cp++ = 0; /* add null termination */
- extraFlag = 0;
- if ((flags & CM_FLAG_DIRSEARCH) && tc == 0)
- extraFlag = CM_FLAG_NOMOUNTCHASE;
- code = cm_Lookup(tscp, component,
- flags | extraFlag,
- userp, reqp, &nscp);
- if (code) {
- cm_ReleaseSCache(tscp);
- if (psp) cm_FreeSpace(psp);
- return code;
- }
- haveComponent = 0; /* component done */
- dirScp = tscp; /* for some symlinks */
- tscp = nscp; /* already held */
- if (tc == 0 && !(flags & CM_FLAG_FOLLOW) && phase == 2) {
- code = 0;
- cm_ReleaseSCache(dirScp);
- break;
- }
-
- /* now, if tscp is a symlink, we should follow
- * it and assemble the path again.
- */
- lock_ObtainMutex(&tscp->mx);
- code = cm_SyncOp(tscp, NULL, userp, reqp, 0,
- CM_SCACHESYNC_GETSTATUS
- | CM_SCACHESYNC_NEEDCALLBACK);
- if (code) {
- lock_ReleaseMutex(&tscp->mx);
- cm_ReleaseSCache(tscp);
- cm_ReleaseSCache(dirScp);
- break;
- }
- if (tscp->fileType == CM_SCACHETYPE_SYMLINK) {
- /* this is a symlink; assemble a new buffer */
- lock_ReleaseMutex(&tscp->mx);
- if (symlinkCount++ >= 16) {
- cm_ReleaseSCache(tscp);
- cm_ReleaseSCache(dirScp);
- if (psp) cm_FreeSpace(psp);
- return CM_ERROR_TOOBIG;
- }
- if (tc == 0) restp = "";
- else restp = tp;
- code = cm_AssembleLink(tscp, restp,
- &linkScp, &tempsp, userp, reqp);
- if (code) {
- /* something went wrong */
- cm_ReleaseSCache(tscp);
- cm_ReleaseSCache(dirScp);
- break;
- }
-
- /* otherwise, tempsp has the new path,
- * and linkScp is the new root from
- * which to interpret that path.
- * Continue with the namei processing,
- * also doing the bookkeeping for the
- * space allocation and tracking the
- * vnode reference counts.
- */
- if (psp) cm_FreeSpace(psp);
- psp = tempsp;
- tp = psp->data;
- cm_ReleaseSCache(tscp);
- tscp = linkScp; /* already held
- * by AssembleLink */
- /* now, if linkScp is null, that's
- * AssembleLink's way of telling us that
- * the sym link is relative to the dir
- * containing the link. We have a ref
- * to it in dirScp, and we hold it now
- * and reuse it as the new spot in the
- * dir hierarchy.
- */
- if (tscp == NULL) {
- cm_HoldSCache(dirScp);
- tscp = dirScp;
- }
- } /* if we have a sym link */
- else {
- /* not a symlink, we may be done */
- lock_ReleaseMutex(&tscp->mx);
- if (tc == 0) {
- if (phase == 1) {
- phase = 2;
- tp = pathp;
- continue;
- }
- cm_ReleaseSCache(dirScp);
- code = 0;
- break;
- }
- }
- cm_ReleaseSCache(dirScp);
- } /* end of a component */
- else *cp++ = tc;
- } /* we have a component */
- } /* big while loop over all components */
+ if (tc == 0) restp = "";
+ else restp = tp;
+ code = cm_AssembleLink(tscp, restp, &linkScp, &tempsp, userp, reqp);
+ if (code) {
+ /* something went wrong */
+ cm_ReleaseSCache(tscp);
+ cm_ReleaseSCache(dirScp);
+ break;
+ }
+
+ /* otherwise, tempsp has the new path,
+ * and linkScp is the new root from
+ * which to interpret that path.
+ * Continue with the namei processing,
+ * also doing the bookkeeping for the
+ * space allocation and tracking the
+ * vnode reference counts.
+ */
+ if (psp) cm_FreeSpace(psp);
+ psp = tempsp;
+ tp = psp->data;
+ cm_ReleaseSCache(tscp);
+ tscp = linkScp; /* already held
+ * by AssembleLink */
+ /* now, if linkScp is null, that's
+ * AssembleLink's way of telling us that
+ * the sym link is relative to the dir
+ * containing the link. We have a ref
+ * to it in dirScp, and we hold it now
+ * and reuse it as the new spot in the
+ * dir hierarchy.
+ */
+ if (tscp == NULL) {
+ cm_HoldSCache(dirScp);
+ tscp = dirScp;
+ }
+ } /* if we have a sym link */
+ else {
+ /* not a symlink, we may be done */
+ lock_ReleaseMutex(&tscp->mx);
+ if (tc == 0) {
+ if (phase == 1) {
+ phase = 2;
+ tp = pathp;
+ continue;
+ }
+ cm_ReleaseSCache(dirScp);
+ code = 0;
+ break;
+ }
+ }
+ cm_ReleaseSCache(dirScp);
+ } /* end of a component */
+ else *cp++ = tc;
+ } /* we have a component */
+ } /* big while loop over all components */
/* already held */
- if (psp) cm_FreeSpace(psp);
+ if (psp) cm_FreeSpace(psp);
if (code == 0) *outScpp = tscp;
return code;
}
}
/* get hostname or addr, given addr in network byte order */
-char *hostutil_GetNameByINet(long addr)
+char *hostutil_GetNameByINet(afs_uint32 addr)
{
static char hostNameBuffer[256];
struct hostent *thp;
- thp = gethostbyaddr((char *) &addr, sizeof(long), AF_INET);
+ thp = gethostbyaddr((char *) &addr, sizeof(afs_uint32), AF_INET);
if (thp)
strcpy(hostNameBuffer, thp->h_name);
else {
/* Fake error code since NT errno.h doesn't define it */
#include <afs/errmap_nt.h>
-//extern char *hostutil_GetNameByINet(long addr);
+#ifndef hostutil_GetNameByINet
+extern char *hostutil_GetNameByINet(afs_uint32 addr);
+#endif
#ifndef hostutil_GetHostByName
extern struct hostent *hostutil_GetHostByName(char *namep);
--- /dev/null
+#include <afx.h>
+#include <windows.h>
+#include <winreg.h>
+#include <nb30.h>
+#include <tchar.h>
+#include <shellapi.h>
+#include <objbase.h>
+#include <shlobj.h>
+#include <shlwapi.h>
+#include <wtypes.h>
+#include <string.h>
+#include <malloc.h>
+#include "lanahelper.h"
+
+
+extern "C" void afsi_log(...);
+
+static HRESULT getname_shellfolder(WCHAR *wGuid, WCHAR *wName, int NameSize)
+{
+ // This is the GUID for the network connections folder. It is constant.
+ // {7007ACC7-3202-11D1-AAD2-00805FC1270E}
+ const GUID CLSID_NetworkConnections = {
+ 0x7007ACC7, 0x3202, 0x11D1, {
+ 0xAA, 0xD2, 0x00, 0x80, 0x5F, 0xC1, 0x27, 0x0E
+ }
+ };
+ LPITEMIDLIST pidl;
+ IShellFolder *pShellFolder;
+ IMalloc *pShellMalloc;
+
+ // Build the display name in the form "::{GUID}".
+ if (wcslen(wGuid) >= MAX_PATH)
+ return E_INVALIDARG;
+ WCHAR szAdapterGuid[MAX_PATH + 2];
+ swprintf(szAdapterGuid, L"::%ls", wGuid);
+
+ // Initialize COM.
+ CoInitialize(NULL);
+
+ // Get the shell allocator.
+ HRESULT hr = SHGetMalloc(&pShellMalloc);
+ if (SUCCEEDED(hr))
+ // Create an instance of the network connections folder.
+ hr = CoCreateInstance(CLSID_NetworkConnections, NULL,
+ CLSCTX_INPROC_SERVER, IID_IShellFolder,
+ reinterpret_cast<LPVOID *>(&pShellFolder));
+ if (SUCCEEDED(hr))
+ hr = pShellFolder->ParseDisplayName(NULL, NULL, szAdapterGuid, NULL,
+ &pidl, NULL);
+ if (SUCCEEDED(hr)) {
+ // Get the display name; this returns the friendly name.
+ STRRET sName;
+ hr = pShellFolder->GetDisplayNameOf(pidl, SHGDN_NORMAL, &sName);
+ if (SUCCEEDED(hr))
+ wcsncpy(wName, sName.pOleStr, NameSize);
+ pShellMalloc->Free(pidl);
+ }
+
+ CoUninitialize();
+ return hr;
+}
+
+// Get the Connection Name for the given GUID.
+extern "C" int lana_GetNameFromGuid(char *Guid, char **Name)
+{
+ typedef HRESULT (WINAPI *HrLanProcAddr)(GUID *, PCWSTR, PWSTR, LPDWORD);
+ HrLanProcAddr HrLanProc = NULL;
+ HMODULE hNetMan;
+ int size;
+ WCHAR *wGuid = NULL;
+ WCHAR wName[MAX_PATH];
+ DWORD NameSize = (sizeof(wName) / sizeof(wName[0]));
+ HRESULT status;
+
+ // Convert the Guid string to Unicode. First we ask only for the size
+ // of the converted string. Then we allocate a buffer of sufficient
+ // size to hold the result of the conversion.
+ size = MultiByteToWideChar(CP_ACP, 0, Guid, -1, NULL, 0);
+ wGuid = (WCHAR *) malloc(size * sizeof(WCHAR));
+ MultiByteToWideChar(CP_ACP, 0, Guid, -1, wGuid, size);
+
+ // First try the IShellFolder interface, which was unimplemented
+ // for the network connections folder before XP.
+
+ /* XXX pbh 9/11/03 - revert to using the undocumented APIs on XP while
+ * waiting tohear back from PSS about the slow reboot issue.
+ * This is an ungly, misleading hack, but is minimally invasive
+ * and will be easy to rollback.
+ */
+
+ //status = getname_shellfolder(wGuid, wName, NameSize);
+ status = E_NOTIMPL;
+
+ /* XXX end of pbh 9/11/03 temporary hack*/
+
+ if (status == E_NOTIMPL) {
+ // The IShellFolder interface is not implemented on this platform.
+ // Try the (undocumented) HrLanConnectionNameFromGuidOrPath API
+ // from the netman DLL.
+ afsi_log("IShellFolder API not implemented, trying HrLanConnectionNameFromGuidOrPath");
+ hNetMan = LoadLibrary("netman.dll");
+ if (hNetMan == NULL) {
+ free(wGuid);
+ return -1;
+ }
+ HrLanProc =
+ (HrLanProcAddr) GetProcAddress(hNetMan,
+ "HrLanConnectionNameFromGuidOrPath");
+ if (HrLanProc == NULL) {
+ FreeLibrary(hNetMan);
+ free(wGuid);
+ return -1;
+ }
+ status = HrLanProc(NULL, wGuid, wName, &NameSize);
+ FreeLibrary(hNetMan);
+ }
+ free(wGuid);
+ if (FAILED(status)) {
+ afsi_log("lana_GetNameFromGuid: failed to get connection name (status %ld)",
+ status);
+ return -1;
+ }
+
+ // Get the required buffer size, and then convert the string.
+ size = WideCharToMultiByte(CP_ACP, 0, wName, -1, NULL, 0, NULL, NULL);
+ *Name = (char *) malloc(size);
+ if (*Name == NULL)
+ return -1;
+ WideCharToMultiByte(CP_ACP, 0, wName, -1, *Name, size, NULL, NULL);
+ afsi_log("Connection name for %s is '%s'", Guid, *Name);
+ return 0;
+}
+
+// Find the lana number for the given connection name.
+extern "C" lana_number_t lana_FindLanaByName(const char *LanaName)
+{
+ const char RegNetBiosLinkageKeyName[] =
+ "System\\CurrentControlSet\\Services\\NetBios\\Linkage";
+ HKEY hkey;
+ LONG status;
+ struct {
+ BYTE flags;
+ BYTE number;
+ } lanamap[MAX_LANA+1];
+ DWORD lanamapsize = sizeof(lanamap);
+ DWORD type;
+ char *bindpaths = NULL;
+ DWORD bindpathsize;
+ int nlana;
+ int i;
+ char *guid;
+ char *name;
+ char *pBind;
+ char *p;
+
+ // Open the NetBios Linkage key.
+ status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, RegNetBiosLinkageKeyName, 0,
+ KEY_QUERY_VALUE, &hkey);
+
+ if (status != ERROR_SUCCESS) {
+ afsi_log("Failed to open NetBios Linkage key (status %ld)", status);
+ return LANA_INVALID;
+ }
+
+ // Read the lana map.
+ status = RegQueryValueEx(hkey, "LanaMap", 0, &type,
+ (BYTE *) &lanamap, &lanamapsize);
+ if (status != ERROR_SUCCESS) {
+ afsi_log("Failed to read LanaMap (status %ld)", status);
+ RegCloseKey(hkey);
+ return LANA_INVALID;
+ }
+ if (lanamapsize == 0) {
+ afsi_log("No data in LanaMap");
+ return LANA_INVALID;
+ }
+ nlana = lanamapsize / sizeof(lanamap[0]);
+
+ // Get the bind paths for NetBios so we can match them up
+ // with the lana map. First we query for the size, so we
+ // can allocate an appropriate buffer.
+ status = RegQueryValueEx(hkey, "Bind", 0, &type, NULL, &bindpathsize);
+ if (status == ERROR_SUCCESS && bindpathsize != 0) {
+ bindpaths = (char *) malloc(bindpathsize * sizeof(char));
+ if (bindpaths == NULL) {
+ afsi_log("Cannot allocate %ld bytes for bindpaths", bindpathsize);
+ RegCloseKey(hkey);
+ return LANA_INVALID;
+ }
+ status = RegQueryValueEx(hkey, "Bind", 0, &type,
+ (BYTE *) bindpaths, &bindpathsize);
+ }
+ RegCloseKey(hkey);
+ if (status != ERROR_SUCCESS) {
+ afsi_log("Failed to read bind paths (status %ld)", status);
+ if (bindpaths != NULL)
+ free(bindpaths);
+ return LANA_INVALID;
+ }
+ if (bindpathsize == 0) {
+ afsi_log("No bindpath data");
+ if (bindpaths != NULL)
+ free(bindpaths);
+ return LANA_INVALID;
+ }
+
+ // Iterate over the lana map entries and bind paths.
+ for (i = 0, pBind = bindpaths; i < nlana;
+ i++, pBind += strlen(pBind) + 1) {
+ // Ignore an invalid map entry.
+ if ((lanamap[i].flags & 1) == 0)
+ continue;
+
+ // check for a IPv4 binding
+ if(!strstr(pBind,"_Tcpip_"))
+ continue;
+
+ // Find the beginning of the GUID.
+ guid = strchr(pBind, '{');
+ if (guid == NULL)
+ continue; // Malformed path entry?
+ guid = strdup(guid);
+ if (guid == NULL)
+ continue;
+ // Find the end of the GUID.
+ p = strchr(guid, '}');
+ if (p == NULL) {
+ free(guid); // Malformed GUID?
+ continue;
+ }
+ *++p = '\0'; // Ignore anything after the GUID.
+ status = lana_GetNameFromGuid(guid, &name);
+ free(guid);
+ if (status == 0) {
+ status = strcmp(name, LanaName);
+ free(name);
+ if (status == 0) {
+ free(bindpaths);
+ afsi_log("lana_FindLanaByName: Found lana %d for %s",
+ lanamap[i].number, LanaName);
+ return lanamap[i].number;
+ }
+ }
+ }
+ free(bindpaths);
+ return LANA_INVALID;
+}
+
+extern "C" lana_number_t lana_FindLoopback(void)
+{
+ NCB ncb;
+ LANA_ENUM lana_list;
+ int status;
+ int i;
+
+ memset(&ncb, 0, sizeof(ncb));
+ ncb.ncb_command = NCBENUM;
+ ncb.ncb_buffer = (UCHAR *) &lana_list;
+ ncb.ncb_length = sizeof(lana_list);
+ status = Netbios(&ncb);
+ if (status != 0) {
+ afsi_log("Netbios NCBENUM failed: status %ld", status);
+ return LANA_INVALID;
+ }
+ for (i = 0; i < lana_list.length; i++) {
+ if (lana_IsLoopback(lana_list.lana[i])) {
+ // Found one, return it.
+ afsi_log("lana_FindLoopback: Found LAN adapter %d",
+ lana_list.lana[i]);
+ return lana_list.lana[i];
+ }
+ }
+ // Could not find a loopback adapter.
+ return LANA_INVALID;
+}
+
+// Is the given lana a Windows Loopback Adapter?
+extern "C" BOOL lana_IsLoopback(lana_number_t lana)
+{
+ NCB ncb;
+ struct {
+ ADAPTER_STATUS status;
+ NAME_BUFFER names[MAX_LANA+1];
+ } astat;
+ unsigned char kWLA_MAC[6] = { 0x02, 0x00, 0x4c, 0x4f, 0x4f, 0x50 };
+ int status;
+
+ // Reset the adapter: in Win32, this is required for every process, and
+ // acts as an init call, not as a real hardware reset.
+ memset(&ncb, 0, sizeof(ncb));
+ ncb.ncb_command = NCBRESET;
+ ncb.ncb_callname[0] = 100;
+ ncb.ncb_callname[2] = 100;
+ ncb.ncb_lana_num = lana;
+ status = Netbios(&ncb);
+ if (status == 0)
+ status = ncb.ncb_retcode;
+ if (status != 0) {
+ afsi_log("NCBRESET failed: lana %u, status %ld", lana, status);
+ return FALSE;
+ }
+
+ // Use the NCBASTAT command to get the adapter address.
+ memset(&ncb, 0, sizeof(ncb));
+ ncb.ncb_command = NCBASTAT;
+ ncb.ncb_lana_num = lana;
+ strcpy((char *) ncb.ncb_callname, "* ");
+ ncb.ncb_buffer = (UCHAR *) &astat;
+ ncb.ncb_length = sizeof(astat);
+ status = Netbios(&ncb);
+ if (status == 0)
+ status = ncb.ncb_retcode;
+ if (ncb.ncb_retcode != 0) {
+ afsi_log("NCBASTAT failed: lana %u, status %ld", lana, status);
+ return FALSE;
+ }
+ return (memcmp(astat.status.adapter_address, kWLA_MAC, 6) == 0);
+}
--- /dev/null
+#include <windows.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ typedef BYTE lana_number_t;
+
+#define LANA_INVALID 0xff
+
+ int lana_GetNameFromGuid(char *Guid, char **Name);
+
+ lana_number_t lana_FindLanaByName(const char *LanaName);
+
+ lana_number_t lana_FindLoopback(void);
+
+ BOOL lana_IsLoopback(lana_number_t lana);
+
+#ifdef __cplusplus
+}
+#endif
#include "afsd.h"
#include "smb.h"
+#include "lanahelper.h"
/* These characters are illegal in Windows filenames */
static char *illegalChars = "\\/:*?\"<>|";
smb_vc_t *dead_vcp = NULL;
smb_vc_t *active_vcp = NULL;
+/* TODO; logout mechanism needs to be thread-safe */
char *loggedOutName = NULL;
smb_user_t *loggedOutUserp = NULL;
unsigned long loggedOutTime;
int numNCBs, numSessions;
+int smb_maxVCPerServer;
+int smb_maxMpxRequests;
+
#define NCBmax 100
EVENT_HANDLE NCBavails[NCBmax], NCBevents[NCBmax];
EVENT_HANDLE **NCBreturns;
smb_dirSearch_t *smb_firstDirSearchp;
smb_dirSearch_t *smb_lastDirSearchp;
+/* hide dot files? */
+int smb_hideDotFiles;
+
/* global state about V3 protocols */
int smb_useV3; /* try to negotiate V3 */
/* Time difference for converting to kludge-GMT */
int smb_NowTZ;
-char *smb_localNamep;
+char *smb_localNamep = NULL;
smb_vc_t *smb_allVCsp;
NCB *ncbp, raw_write_cont_t *rwcp);
void smb_NetbiosInit();
#ifdef DJGPP
+#ifndef AFS_WIN95_ENV
+DWORD smb_ServerExceptionFilter(void);
+#endif
+
extern char cm_HostName[];
extern char cm_confDir[];
#endif
if (scp->fileType == CM_SCACHETYPE_DIRECTORY
|| scp->fileType == CM_SCACHETYPE_MOUNTPOINT)
- attrs = 0x10;
+ attrs = SMB_ATTR_DIRECTORY;
else
attrs = 0;
if ((scp->unixModeBits & 0222) == 0 || (scp->flags & CM_SCACHEFLAG_RO))
#endif
if ((scp->unixModeBits & 0222) == 0)
- attrs |= 1; /* turn on read-only flag */
+ attrs |= SMB_ATTR_READONLY; /* turn on read-only flag */
return attrs;
}
+/* Check if the named file/dir is a dotfile/dotdir */
+/* String pointed to by lastComp can have leading slashes, but otherwise should have
+ no other patch components */
+unsigned int smb_IsDotFile(char *lastComp) {
+ char *s;
+ if(lastComp) {
+ /* skip over slashes */
+ for(s=lastComp;*s && (*s == '\\' || *s == '/'); s++);
+ }
+ else
+ return 0;
+
+ /* nulls, curdir and parent dir doesn't count */
+ if(!*s) return 0;
+ if(*s == '.') {
+ if(!*(s + 1)) return 0;
+ if(*(s+1) == '.' && !*(s + 2)) return 0;
+ return 1;
+ }
+ return 0;
+}
+
static int ExtractBits(WORD bits, short start, short len)
{
int end;
if (!unp && (flags & SMB_FLAG_CREATE)) {
unp = malloc(sizeof(*unp));
memset(unp, 0, sizeof(*unp));
+ unp->refCount = 1;
unp->nextp = usernamesp;
unp->name = strdup(usern);
unp->machine = strdup(machine);
char *tpath;
tidp = smb_FindTID(vcp, tid, 0);
+ if (!tidp)
+ return NULL;
tpath = tidp->pathname;
smb_ReleaseTID(tidp);
return tpath;
smb_vc_t *vcp;
smb_ioctl_t *ioctlp;
+ if (!fidp)
+ return NULL;
+
scp = NULL;
lock_ObtainWrite(&smb_rctLock);
osi_assert(fidp->refCount-- > 0);
else
smb_subst(p, var, sizeof(VNUserName),
" ");
- smb_ReleaseUID(uidp);
+ if (uidp)
+ smb_ReleaseUID(uidp);
}
else if (var = smb_stristr(p, VNLCUserName)) {
uidp = smb_FindUID(vcp, ((smb_t *)inp)->uid, 0);
else strcpy(temp, " ");
_strlwr(temp);
smb_subst(p, var, sizeof(VNLCUserName), temp);
- smb_ReleaseUID(uidp);
+ if (uidp)
+ smb_ReleaseUID(uidp);
}
else if (var = smb_stristr(p, VNComputerName)) {
sizeTemp = sizeof(temp);
lock_ObtainWrite(&smb_globalLock);
tbp = smb_packetFreeListp;
- if (tbp) smb_packetFreeListp = tbp->nextp;
+ if (tbp)
+ smb_packetFreeListp = tbp->nextp;
lock_ReleaseWrite(&smb_globalLock);
if (!tbp) {
#ifndef DJGPP
tbp->oddByte = 0;
tbp->ncb_length = 0;
tbp->flags = 0;
+ tbp->spacep = NULL;
#ifdef DJGPP
npar = SMB_PACKETSIZE >> 4; /* number of paragraphs */
/* compute size of protocol entry */
entryLength = strlen(namep+1);
- entryLength += 2; /* 0x02 bytes and null termination */
+ entryLength += 2; /* 0x02 bytes and null termination */
- /* advance over this protocol entry */
+ /* advance over this protocol entry */
namex += entryLength;
- namep += entryLength;
- tcounter++; /* which proto entry we're looking at */
+ namep += entryLength;
+ tcounter++; /* which proto entry we're looking at */
}
#ifndef NOMOREFILESFIX
/*
* ie. the order in which it sends us the protocol list.
*
* Special handling for Windows 2000 clients (defect 11765 )
+ * <asanka:11Jun03> Proto signature is the same for Win XP. </>
*/
if (tcounter == 6) {
int i = 0;
*/
}
}
- // NOMOREFILESFIX
-#endif
+#endif /* NOMOREFILESFIX */
if (NTProtoIndex != -1) {
protoIndex = NTProtoIndex;
return CM_ERROR_INVAL;
else if (NTProtoIndex != -1) {
smb_SetSMBParm(outp, 0, protoIndex);
- smb_SetSMBParmByte(outp, 1, 0); /* share level security, no passwd encrypt */
- smb_SetSMBParm(outp, 1, 8); /* max multiplexed requests */
- smb_SetSMBParm(outp, 2, 100); /* max VCs per consumer/server connection */
- smb_SetSMBParmLong(outp, 3, SMB_PACKETSIZE); /* xmit buffer size */
+ smb_SetSMBParmByte(outp, 1, 0); /* share level security, no passwd encrypt */
+ smb_SetSMBParm(outp, 1, smb_maxMpxRequests); /* max multiplexed requests */
+ smb_SetSMBParm(outp, 2, smb_maxVCPerServer); /* max VCs per consumer/server connection */
+ smb_SetSMBParmLong(outp, 3, SMB_PACKETSIZE); /* xmit buffer size */
smb_SetSMBParmLong(outp, 5, 65536); /* raw buffer size */
- smb_SetSMBParm(outp, 7, 1); /* next 2: session key */
- smb_SetSMBParm(outp, 8, 1);
+ smb_SetSMBParm(outp, 7, 1); /* next 2: session key */
+ smb_SetSMBParm(outp, 8, 1);
/*
* Tried changing the capabilities to support for W2K - defect 117695
* Maybe something else needs to be changed here?
smb_SetSMBParm(outp, 0, protoIndex);
smb_SetSMBParm(outp, 1, 0); /* share level security, no passwd encrypt */
smb_SetSMBParm(outp, 2, SMB_PACKETSIZE);
- smb_SetSMBParm(outp, 3, 8); /* max multiplexed requests */
- smb_SetSMBParm(outp, 4, 100); /* max VCs per consumer/server connection */
+ smb_SetSMBParm(outp, 3, smb_maxMpxRequests); /* max multiplexed requests */
+ smb_SetSMBParm(outp, 4, smb_maxVCPerServer); /* max VCs per consumer/server connection */
smb_SetSMBParm(outp, 5, 0); /* no support of block mode for read or write */
smb_SetSMBParm(outp, 6, 1); /* next 2: session key */
smb_SetSMBParm(outp, 7, 1);
/* names starting with a dot are illegal */
if (*tp == '.') valid8Dot3 = 0;
- for(i=0;; i++) {
+ for(i=0;; i++) {
tc = *tp++;
- if (tc == 0) return valid8Dot3;
- if (tc == '.' || tc == '"') break;
- if (i < 8) *up++ = tc;
- else valid8Dot3 = 0;
- }
+ if (tc == 0) return valid8Dot3;
+ if (tc == '.' || tc == '"') break;
+ if (i < 8) *up++ = tc;
+ else valid8Dot3 = 0;
+ }
- /* if we get here, tp point after the dot */
- up = maskp+8; /* ext goes here */
- for(i=0;;i++) {
- tc = *tp++;
- if (tc == 0) return valid8Dot3;
-
- /* too many dots */
- if (tc == '.' || tc == '"') valid8Dot3 = 0;
+ /* if we get here, tp point after the dot */
+ up = maskp+8; /* ext goes here */
+ for(i=0;;i++) {
+ tc = *tp++;
+ if (tc == 0) return valid8Dot3;
- /* copy extension if not too long */
- if (i < 3) *up++ = tc;
- else valid8Dot3 = 0;
- }
+ /* too many dots */
+ if (tc == '.' || tc == '"') valid8Dot3 = 0;
+
+ /* copy extension if not too long */
+ if (i < 3) *up++ = tc;
+ else valid8Dot3 = 0;
+ }
+
+ /* unreachable */
}
int smb_Match8Dot3Mask(char *unixNamep, char *maskp)
attr = smb_Attributes(scp);
*dptr++ = attr;
+ /* check hidden attribute (the flag is only ON when dot file hiding is on ) */
+ if( patchp->flags & SMB_DIRLISTPATCH_DOTFILE )
+ attr |= SMB_ATTR_HIDDEN;
+
/* get dos time */
smb_SearchTimeFromUnixTime(&dosTime, scp->clientModTime);
if (attribute & 0x8)
return smb_ReceiveCoreSearchVolume(vcp, inp, outp);
- osi_Log2(afsd_logp, "SMB receive search dir count %d |%s|",
+ osi_Log2(afsd_logp, "SMB receive search dir count %d [%s]",
maxCount, osi_LogSaveString(afsd_logp, pathp));
if (*pathp == 0) { /* null pathp, treat as root dir */
- if (!(attribute & 0x10)) /* exclude dirs */
+ if (!(attribute & SMB_ATTR_DIRECTORY)) /* exclude dirs */
return CM_ERROR_NOFILES;
rootPath = 1;
}
actualName = shortName;
}
- if (dep->fid.vnode != 0 && smb_Match8Dot3Mask(actualName, mask)) {
- /* this is one of the entries to use: it is not deleted
- * and it matches the star pattern we're looking for.
- */
+ if (dep->fid.vnode != 0 && smb_Match8Dot3Mask(actualName, mask)) {
+ /* this is one of the entries to use: it is not deleted
+ * and it matches the star pattern we're looking for.
+ */
- /* Eliminate entries that don't match requested
- attributes */
- if (!(dsp->attribute & 0x10)) /* no directories */
- {
+ /* Eliminate entries that don't match requested
+ attributes */
+
+ /* no hidden files */
+ if(smb_hideDotFiles && !(dsp->attribute & SMB_ATTR_HIDDEN) && smb_IsDotFile(actualName))
+ goto nextEntry;
+
+ if (!(dsp->attribute & SMB_ATTR_DIRECTORY)) /* no directories */
+ {
/* We have already done the cm_TryBulkStat above */
fid.cell = scp->fid.cell;
fid.volume = scp->fid.volume;
* The replay will happen at a time when it is safe to
* unlock the directory.
*/
- curPatchp = malloc(sizeof(*curPatchp));
- osi_QAdd((osi_queue_t **) &dirListPatchesp, &curPatchp->q);
- curPatchp->dptr = op;
- curPatchp->fid.cell = scp->fid.cell;
- curPatchp->fid.volume = scp->fid.volume;
- curPatchp->fid.vnode = ntohl(dep->fid.vnode);
- curPatchp->fid.unique = ntohl(dep->fid.unique);
- op += 9; /* skip attr, time, date and size */
+ curPatchp = malloc(sizeof(*curPatchp));
+ osi_QAdd((osi_queue_t **) &dirListPatchesp, &curPatchp->q);
+ curPatchp->dptr = op;
+ curPatchp->fid.cell = scp->fid.cell;
+ curPatchp->fid.volume = scp->fid.volume;
+ curPatchp->fid.vnode = ntohl(dep->fid.vnode);
+ curPatchp->fid.unique = ntohl(dep->fid.unique);
+
+ /* do hidden attribute here since name won't be around when applying
+ * dir list patches
+ */
+
+ if ( smb_hideDotFiles && smb_IsDotFile(actualName) )
+ curPatchp->flags = SMB_DIRLISTPATCH_DOTFILE;
+ else
+ curPatchp->flags = 0;
+
+ op += 9; /* skip attr, time, date and size */
/* zero out name area. The spec says to pad with
* spaces, but Samba doesn't, and neither do we.
*/
spacep = inp->spacep;
smb_StripLastComponent(spacep->data, &lastComp, pathp);
- if (strcmp(lastComp, "\\desktop.ini") == 0) {
+ if (lastComp && stricmp(lastComp, "\\desktop.ini") == 0) {
code = cm_NameI(rootScp, spacep->data,
caseFold | CM_FLAG_DIRSEARCH | CM_FLAG_FOLLOW,
userp, tidPathp, &req, &dscp);
return code;
}
+#ifdef undef
+ /* use smb_Attributes instead. Also the fact that a file is in a readonly volume
+ doesn't mean it shojuld be marked as RO */
+
if (newScp->fileType == CM_SCACHETYPE_DIRECTORY
|| newScp->fileType == CM_SCACHETYPE_MOUNTPOINT)
- attrs = 0x10;
+ attrs = SMB_ATTR_DIRECTORY;
else
attrs = 0;
if ((newScp->unixModeBits & 0222) == 0 || (newScp->flags & CM_SCACHEFLAG_RO))
- attrs |= 1; /* turn on read-only flag */
+ attrs |= SMB_ATTR_READONLY; /* turn on read-only flag */
+#else
+ attrs = smb_Attributes(newScp);
+#endif
+
smb_SetSMBParm(outp, 0, attrs);
smb_DosUTimeFromUnixTime(&dosTime, newScp->clientModTime);
cm_InitReq(&req);
- osi_Log0(afsd_logp, "SMB receive open");
-
- pathp = smb_GetSMBData(inp, NULL);
- pathp = smb_ParseASCIIBlock(pathp, NULL);
+ pathp = smb_GetSMBData(inp, NULL);
+ pathp = smb_ParseASCIIBlock(pathp, NULL);
+ osi_Log1(afsd_logp, "SMB receive open file [%s]", osi_LogSaveString(afsd_logp, pathp));
+
+#ifdef DEBUG_VERBOSE
+ {
+ char *hexpath;
+
+ hexpath = osi_HexifyString( pathp );
+ DEBUG_EVENT2("AFS", "CoreOpen H[%s] A[%s]", hexpath, pathp);
+ free(hexpath);
+ }
+#endif
+
share = smb_GetSMBParm(inp, 0);
attribute = smb_GetSMBParm(inp, 1);
rock.hasTilde = ((strchr(oldLastNamep, '~') != NULL) ? 1 : 0);
rock.newNamep = newLastNamep;
- /* now search the dir for the pattern, and do the appropriate rename when
- * found.
- */
- thyper.LowPart = 0; /* search dir from here */
- thyper.HighPart = 0;
- /* search for file to already exhist, if so return error*/
-
+ /* Check if the file already exists; if so return error */
code = cm_Lookup(newDscp,newLastNamep,CM_FLAG_CHECKPATH,userp,&req,&tmpscp);
if((code != CM_ERROR_NOSUCHFILE) && (code != CM_ERROR_NOSUCHPATH) && (code != CM_ERROR_NOSUCHVOLUME) ) {
cm_ReleaseSCache(tmpscp);
return CM_ERROR_EXISTS; /* file exist, do not rename, also
fixes move*/
}
- code = cm_ApplyDir(oldDscp, smb_RenameProc, &rock, &thyper, userp, &req, NULL);
- if (code == CM_ERROR_STOPNOW)
+ /* Now search the directory for the pattern, and do the appropriate rename when found */
+ thyper.LowPart = 0; /* search dir from here */
+ thyper.HighPart = 0;
+
+ code = cm_ApplyDir(oldDscp, smb_RenameProc, &rock, &thyper, userp, &req, NULL);
+
+ if (code == CM_ERROR_STOPNOW)
code = 0;
else if (code == 0)
code = CM_ERROR_NOSUCHFILE;
if (!smb_IsLegalFilename(lastNamep))
return CM_ERROR_BADNTFILENAME;
- code = cm_Lookup(dscp, lastNamep, caseFold, userp, &req, &scp);
+ osi_Log1(afsd_logp, "SMB receive create [%s]", osi_LogSaveString( afsd_logp, pathp ));
+#ifdef DEBUG_VERBOSE
+ {
+ char *hexp;
+ hexp = osi_HexifyString( lastNamep );
+ DEBUG_EVENT2("AFS", "CoreCreate H[%s] A[%s]", hexp, lastNamep );
+ free(hexp);
+ }
+#endif
+
+code = cm_Lookup(dscp, lastNamep, caseFold, userp, &req, &scp);
if (code && code != CM_ERROR_NOSUCHFILE) {
cm_ReleaseSCache(dscp);
cm_ReleaseUser(userp);
}
else {
/* bad opcode, fail the request, after displaying it */
+#ifdef NOTSERVICE
+ smb_LogPacket(inp);
+#endif /* NOTSERVICE */
+
#ifndef DJGPP
if (showErrors) {
sprintf(tbuffer, "Received bad SMB req 0x%x", inp->inCom);
ReportEvent(h, EVENTLOG_ERROR_TYPE, 0, 1002, NULL,
1, ncbp->ncb_length, ptbuf, smbp);
DeregisterEventSource(h);
+#ifdef NOTSERVICE
+ smb_LogPacket(inp);
+#endif /* NOTSERVICE */
#else /* DJGPP */
osi_Log1(afsd_logp, "Invalid SMB message, length %d",
ncbp->ncb_length);
code = thrd_WaitForMultipleObjects_Event(numNCBs, NCBreturns[myIdx],
FALSE, INFINITE);
- if (code == WAIT_OBJECT_0)
+ if (code == WAIT_OBJECT_0) {
continue;
+ }
idx_NCB = code - WAIT_OBJECT_0;
ncbp = NCBs[idx_NCB];
case NRC_PENDING:
/* Can this happen? Or is it just my
- * UNIX paranoia? */
+ * UNIX paranoia?
+ */
continue;
case NRC_SCLOSED:
dead_sessions[idx_session] = TRUE;
vcp = smb_FindVC(ncbp->ncb_lsn, 0, lanas[idx_session]);
/* Should also release vcp. Also, would do
- * sanity check that all TID's are gone. */
- if (dead_vcp)
- osi_Log1(afsd_logp,
- "dead_vcp already set, %x",
- dead_vcp);
- if (!dead_vcp
- && !(vcp->flags & SMB_VCFLAG_ALREADYDEAD)) {
- osi_Log2(afsd_logp,
- "setting dead_vcp %x, user struct %x",
- vcp, vcp->usersp);
- dead_vcp = vcp;
- vcp->flags |= SMB_VCFLAG_ALREADYDEAD;
- }
- if (vcp->justLoggedOut) {
- loggedOut = 1;
- loggedOutTime = vcp->logoffTime;
- loggedOutName =
- strdup(vcp->justLoggedOut->unp->name);
- loggedOutUserp = vcp->justLoggedOut;
- lock_ObtainWrite(&smb_rctLock);
- loggedOutUserp->refCount++;
- lock_ReleaseWrite(&smb_rctLock);
- }
+ * sanity check that all TID's are gone.
+ *
+ * TODO: check if we could use LSNs[idx_session] instead,
+ * also cleanup after dead vcp
+ */
+ if (vcp) {
+ if (dead_vcp)
+ osi_Log1(afsd_logp,
+ "dead_vcp already set, %x",
+ dead_vcp);
+ if (!dead_vcp && !(vcp->flags & SMB_VCFLAG_ALREADYDEAD)) {
+ osi_Log2(afsd_logp,
+ "setting dead_vcp %x, user struct %x",
+ vcp, vcp->usersp);
+ dead_vcp = vcp;
+ vcp->flags |= SMB_VCFLAG_ALREADYDEAD;
+ }
+ if (vcp->justLoggedOut) {
+ loggedOut = 1;
+ loggedOutTime = vcp->logoffTime;
+ loggedOutName =
+ strdup(vcp->justLoggedOut->unp->name);
+ loggedOutUserp = vcp->justLoggedOut;
+ lock_ObtainWrite(&smb_rctLock);
+ loggedOutUserp->refCount++;
+ lock_ReleaseWrite(&smb_rctLock);
+ }
+ }
goto doneWithNCB;
case NRC_INCOMP:
smb_maxObsConcurrentCalls = smb_concurrentCalls;
vcp = smb_FindVC(ncbp->ncb_lsn, 0, ncbp->ncb_lana_num);
+ /*
+ * If at this point vcp is NULL (implies that packet was invalid)
+ * then we are in big trouble. This means either :
+ * a) we have the wrong NCB.
+ * b) Netbios screwed up the call.
+ * Obviously this implies that
+ * ( LSNs[idx_session] != ncbp->ncb_lsn ||
+ * lanas[idx_session] != ncbp->ncb_lana_num )
+ * Either way, we can't do anything with this packet.
+ * Log, sleep and resume.
+ */
+ if(!vcp) {
+ HANDLE h;
+ char buf[1000];
+ char *ptbuf[1];
+
+ sprintf(buf,
+ "Bad vcp!! : "
+ "LSNs[idx_session]=[%d],"
+ "lanas[idx_session]=[%d],"
+ "ncbp->ncb_lsn=[%d],"
+ "ncbp->ncb_lana_num=[%d]",
+ LSNs[idx_session],
+ lanas[idx_session],
+ ncbp->ncb_lsn,
+ ncbp->ncb_lana_num);
+
+ ptbuf[0] = buf;
+
+ h = RegisterEventSource(NULL,AFS_DAEMON_EVENT_NAME);
+ if(h) {
+ ReportEvent(h, EVENTLOG_ERROR_TYPE, 0, 1001, NULL,1,sizeof(*ncbp),ptbuf,(void*)ncbp);
+ DeregisterEventSource(h);
+ }
+
+ /* Also log in the trace log. */
+ osi_Log4(afsd_logp, "Server: BAD VCP!"
+ "LSNs[idx_session]=[%d],"
+ "lanas[idx_session]=[%d],"
+ "ncbp->ncb_lsn=[%d],"
+ "ncbp->ncb_lana_num=[%d]",
+ LSNs[idx_session],
+ lanas[idx_session],
+ ncbp->ncb_lsn,
+ ncbp->ncb_lana_num);
+
+ /* thrd_Sleep(1000); Don't bother sleeping */
+ thrd_SetEvent(SessionEvents[idx_session]);
+ smb_concurrentCalls--;
+ continue;
+ }
+
+
vcp->errorCount = 0;
bufp = (struct smb_packet *) ncbp->ncb_buffer;
#ifdef DJGPP
smbp = (smb_t *)bufp->data;
outbufp->flags = 0;
+#if !defined(DJGPP) && !defined(AFS_WIN32_ENV)
+ __try
+ {
+#endif
if (smbp->com == 0x1d) {
/* Special handling for Write Raw */
raw_write_cont_t rwc;
thrd_SetEvent(SessionEvents[idx_session]);
} else {
thrd_SetEvent(SessionEvents[idx_session]);
+ /* TODO: what else needs to be serialized? */
smb_DispatchPacket(vcp, bufp, outbufp, ncbp, NULL);
}
+#if !defined(DJGPP) && !defined(AFS_WIN95_ENV)
+ }
+ __except( smb_ServerExceptionFilter() ) {
+ }
+#endif
smb_concurrentCalls--;
}
/*
+ * Exception filter for the server threads. If an exception occurs in the
+ * dispatch routines, which is where exceptions are most common, then do a
+ * force trace and give control to upstream exception handlers. Useful for
+ * debugging.
+ */
+#if !defined(DJGPP) && !defined(AFS_WIN95_ENV)
+DWORD smb_ServerExceptionFilter(void) {
+ /* While this is not the best time to do a trace, if it succeeds, then
+ * we have a trace (assuming tracing was enabled). Otherwise, this should
+ * throw a second exception.
+ */
+ HANDLE h;
+ char *ptbuf[1];
+
+ ptbuf[0] = "Unhandled exception forcing trace";
+
+ h = RegisterEventSource(NULL,AFS_DAEMON_EVENT_NAME);
+ if(h) {
+ ReportEvent(h, EVENTLOG_ERROR_TYPE, 0, 1001, NULL,1,0,ptbuf,NULL);
+ DeregisterEventSource(h);
+ }
+
+ afsd_ForceTrace(TRUE);
+ return EXCEPTION_CONTINUE_SEARCH;
+}
+#endif
+
+/*
* Create a new NCB and associated events, packet buffer, and "space" buffer.
* If the number of server threads is M, and the number of live sessions is
* N, then the number of NCB's in use at any time either waiting for, or
dos_ncb = ((smb_ncb_t *)ncbp)->dos_ncb;
#endif /* DJGPP */
+ /* retrieve computer name */
+ GetComputerName(cname, &cnamelen);
+ _strupr(cname);
+
while (1) {
memset(ncbp, 0, sizeof(NCB));
flags = 0;
break;
}
}
- /* get local name and compare */
- GetComputerName(cname, &cnamelen);
- _strupr(cname);
+
+ /* compare with local name */
if (!isGateway)
if (strncmp(rname, cname, NCBNAMSZ) != 0)
flags |= SMB_VCFLAG_REMOTECONN;
sessionGen++;
/* Log session startup */
-#ifdef NOSERVICE
+#ifdef NOTSERVICE
fprintf(stderr, "New session(ncb_lsn,ncb_lana_num) %d,%d starting from host "
"%s\n",
ncbp->ncb_lsn,ncbp->ncb_lana_num, rname);
/* Allocate slot in session arrays */
/* Re-use dead session if possible, otherwise add one more */
- for (i = 0; i < numSessions; i++) {
+ /* But don't look at session[0], it is reserved */
+ for (i = 1; i < numSessions; i++) {
if (dead_sessions[i]) {
dead_sessions[i] = FALSE;
break;
}
}
+
+ /* assert that we do not exceed the maximum number of sessions or NCBs.
+ * we should probably want to wait for a session to be freed in case
+ * we run out.
+ */
+
+ osi_assert(i < Sessionmax && numNCBs < NCBmax - 1);
+
LSNs[i] = ncbp->ncb_lsn;
lanas[i] = ncbp->ncb_lana_num;
if (i == numSessions) {
/* Add new NCB for new session */
+
+ osi_Log1(afsd_logp, "smb_Listener creating new session %d", i);
+
InitNCBslot(numNCBs);
numNCBs++;
thrd_SetEvent(NCBavails[0]);
#ifndef DJGPP
if (smb_LANadapter == -1) {
ncbp->ncb_command = NCBENUM;
- ncbp->ncb_buffer = &lana_list;
+ ncbp->ncb_buffer = (PUCHAR)&lana_list;
ncbp->ncb_length = sizeof(lana_list);
code = Netbios(ncbp);
if (code != 0) {
/* remember the name */
len = strlen(snamep);
- smb_localNamep = malloc(len+1);
- strcpy(smb_localNamep, snamep);
+ smb_localNamep = malloc(len+1);
+ strcpy(smb_localNamep, snamep);
+ afsi_log("smb_localNamep is >%s<", smb_localNamep);
/* and the global lock */
lock_InitializeRWLock(&smb_globalLock, "smb global lock");
smb_dispatchTable[0x0b].procp = smb_ReceiveCoreWrite;
smb_dispatchTable[0x0c].procp = smb_ReceiveCoreLockRecord;
smb_dispatchTable[0x0d].procp = smb_ReceiveCoreUnlockRecord;
- smb_dispatchTable[0x0e].procp = smb_SendCoreBadOp;
+ smb_dispatchTable[0x0e].procp = smb_SendCoreBadOp; /* create temporary */
smb_dispatchTable[0x0f].procp = smb_ReceiveCoreCreate;
smb_dispatchTable[0x10].procp = smb_ReceiveCoreCheckPath;
smb_dispatchTable[0x11].procp = smb_SendCoreBadOp; /* process exit */
}
#endif /* DJGPP */
+/* Get the UNC \\<servername>\<sharename> prefix. */
+char *smb_GetSharename()
+{
+ char *name;
+
+ /* Make sure we have been properly initialized. */
+ if (smb_localNamep == NULL)
+ return NULL;
+
+ /* Allocate space for \\<servername>\<sharename>, plus the
+ * terminator.
+ */
+ name = malloc(strlen(smb_localNamep) + strlen("ALL") + 4);
+ sprintf(name, "\\\\%s\\%s", smb_localNamep, "ALL");
+ return name;
+}
+
+#ifdef NOTSERVICE
+
+void smb_LogPacket(smb_packet_t *packet)
+{
+ BYTE *vp, *cp;
+ unsigned length, paramlen, datalen, i, j;
+ char buf[81];
+ char hex[]={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
+
+ if(!packet) return;
+
+ osi_Log0(afsd_logp, "*** SMB packet dump ***");
+
+ vp = (BYTE *) packet->data;
+
+ datalen = *((WORD*)(vp + (paramlen = ((unsigned)*(vp+20)) << 1)));
+ length = paramlen + 2 + datalen;
+
+
+ for(i=0;i < length; i+=16)
+ {
+ memset( buf, ' ', 80 );
+ buf[80] = 0;
+
+ itoa( i, buf, 16 );
+
+ buf[strlen(buf)] = ' ';
+
+ cp = (BYTE*) buf + 7;
+
+ for(j=0;j < 16 && (i+j)<length; j++)
+ {
+ *(cp++) = hex[vp[i+j] >> 4];
+ *(cp++) = hex[vp[i+j] & 0xf];
+ *(cp++) = ' ';
+
+ if(j==7)
+ {
+ *(cp++) = '-';
+ *(cp++) = ' ';
+ }
+ }
+
+ for(j=0;j < 16 && (i+j)<length;j++)
+ {
+ *(cp++) = ( 32 <= vp[i+j] && 128 > vp[i+j] )? vp[i+j]:'.';
+ if(j==7)
+ {
+ *(cp++) = ' ';
+ *(cp++) = '-';
+ *(cp++) = ' ';
+ }
+ }
+
+ *cp = 0;
+
+ osi_Log0( afsd_logp, buf );
+ }
+
+ osi_Log0(afsd_logp, "*** End SMB packet dump ***");
+
+}
+
+#endif /* NOTSERVICE */
+
int smb_DumpVCP(FILE *outputFile, char *cookie)
{
int zilch;
char output[1024];
- int i;
smb_vc_t *vcp;
#define SMB_FID_LOOKSLIKECOPY (SMB_FID_LENGTHSETDONE | SMB_FID_MTIMESETDONE)
#define SMB_FID_NTOPEN 0x100 /* have dscp and pathp */
+/*
+ * SMB file attributes
+ */
+#define SMB_ATTR_ARCHIVE 0x20
+#define SMB_ATTR_COMPRESSED 0x800 /* file or dir is compressed */
+#define SMB_ATTR_NORMAL 0x80 /* normal file. Only valid if used alone */
+#define SMB_ATTR_HIDDEN 0x2 /* hidden file for the purpose of dir listings */
+#define SMB_ATTR_READONLY 0x1
+#define SMB_ATTR_TEMPORARY 0x100
+#define SMB_ATTR_DIRECTORY 0x10
+#define SMB_ATTR_SYSTEM 0x4
+
/* for tracking in-progress directory searches */
typedef struct smb_dirSearch {
osi_queue_t q; /* queue of all outstanding cookies */
/* type for patching directory listings */
typedef struct smb_dirListPatch {
osi_queue_t q;
- char *dptr; /* ptr to attr, time, data, sizel, sizeh */
+ char *dptr; /* ptr to attr, time, data, sizel, sizeh */
+ long flags; /* flags. See below */
cm_fid_t fid;
cm_dirEntry_t *dep; /* temp */
} smb_dirListPatch_t;
+/* dirListPatch Flags */
+#define SMB_DIRLISTPATCH_DOTFILE 1 /* the file referenced is a dot file
+ Note: will not be set if smb_hideDotFiles is false */
+
/* waiting lock list elements */
typedef struct smb_waitingLock {
osi_queue_t q;
extern int smb_LogoffTokenTransfer;
extern unsigned long smb_LogoffTransferTimeout;
+extern int smb_maxVCPerServer; /* max # of VCs per server */
+extern int smb_maxMpxRequests; /* max # of mpx requests */
+
+extern int smb_hideDotFiles;
+extern unsigned int smb_IsDotFile(char *lastComp);
+
extern void smb_FormatResponsePacket(smb_vc_t *vcp, smb_packet_t *inp,
smb_packet_t *op);
extern BOOL smb_IsLegalFilename(char *filename);
+extern char *smb_GetSharename(void);
+
/* include other include files */
#include "smb3.h"
#include "smb_ioctl.h"
cm_user_t *smb_FindOrCreateUser(smb_vc_t *vcp, char *usern);
+#ifdef NOTSERVICE
+extern void smb_LogPacket(smb_packet_t *packet);
+#endif /* NOTSERVICE */
#endif /* whole file */
* directory or online at http://www.openafs.org/dl/license10.html
*/
-//#define NOSERVICE 1
-
#include <afs/param.h>
#include <afs/stds.h>
if (scp->fileType == CM_SCACHETYPE_DIRECTORY
|| scp->fileType == CM_SCACHETYPE_MOUNTPOINT)
- attrs = 0x10;
+ attrs = SMB_ATTR_DIRECTORY;
else
attrs = 0;
/*
if ((scp->unixModeBits & 0222) == 0 || (scp->flags & CM_SCACHEFLAG_RO))
#endif
if ((scp->unixModeBits & 0222) == 0)
- attrs |= 1; /* Read-only */
+ attrs |= SMB_ATTR_READONLY; /* Read-only */
if (attrs == 0)
- attrs = 0x80; /* FILE_ATTRIBUTE_NORMAL */
+ attrs = SMB_ATTR_NORMAL; /* FILE_ATTRIBUTE_NORMAL */
return attrs;
}
if (!userp)
userp = cm_NewUser();
lock_ObtainMutex(&vcp->mx);
+ if (!vcp->uidCounter)
+ vcp->uidCounter++; /* handle unlikely wraparounds */
newUid = (strlen(usern)==0)?0:vcp->uidCounter++;
lock_ReleaseMutex(&vcp->mx);
inp->flags |= SMB_PACKETFLAG_PROFILE_UPDATE_OK;
/* find the tree and free it */
- uidp = smb_FindUID(vcp, ((smb_t *)inp)->uid, 0);
- if (uidp) {
+ uidp = smb_FindUID(vcp, ((smb_t *)inp)->uid, 0);
+ /* TODO: smb_ReleaseUID() ? */
+ if (uidp) {
char *s1 = NULL, *s2 = NULL;
if (s2 == NULL) s2 = " ";
parmCount, dataCount);
}
- /* now copy the parms and data */
+ /* now copy the parms and data */
+ if ( parmCount != 0 )
+ {
memcpy(((char *)asp->parmsp) + parmDisp, inp->data + parmOffset, parmCount);
+ }
+ if ( dataCount != 0 ) {
memcpy(asp->datap + dataDisp, inp->data + dataOffset, dataCount);
-
+ }
+
/* account for new bytes */
asp->curData += dataCount;
asp->curParms += parmCount;
osi_QRemove((osi_queue_t **) &smb_tran2AssemblyQueuep, &asp->q);
lock_ReleaseWrite(&smb_globalLock);
- /* now dispatch it */
- osi_LogEvent("AFS-Dispatch-2[%s]",myCrt_2Dispatch(asp->opcode),"vcp[%x] lana[%d] lsn[%d]",(int)vcp,vcp->lana,vcp->lsn);
- osi_Log4(afsd_logp,"AFS Server - Dispatch-2 %s vcp[%x] lana[%d] lsn[%d]",myCrt_2Dispatch(asp->opcode),vcp,vcp->lana,vcp->lsn);
+ /* now dispatch it */
+ if ( asp->opcode >= 0 && asp->opcode < 20 && smb_tran2DispatchTable[asp->opcode].procp) {
+ osi_LogEvent("AFS-Dispatch-2[%s]",myCrt_2Dispatch(asp->opcode),"vcp[%x] lana[%d] lsn[%d]",(int)vcp,vcp->lana,vcp->lsn);
+ osi_Log4(afsd_logp,"AFS Server - Dispatch-2 %s vcp[%x] lana[%d] lsn[%d]",myCrt_2Dispatch(asp->opcode),vcp,vcp->lana,vcp->lsn);
code = (*smb_tran2DispatchTable[asp->opcode].procp)(vcp, asp, outp);
+ }
+ else {
+ osi_LogEvent("AFS-Dispatch-2 [invalid]", NULL, "op[%x] vcp[%x] lana[%d] lsn[%d]", asp->opcode, vcp, vcp->lana, vcp->lsn);
+ osi_Log4(afsd_logp,"AFS Server - Dispatch-2 [INVALID] op[%x] vcp[%x] lana[%d] lsn[%d]", asp->opcode, vcp, vcp->lana, vcp->lsn);
+ code = CM_ERROR_BADOP;
+ }
/* if an error is returned, we're supposed to send an error packet,
* otherwise the dispatched function already did the data sending.
return 0;
}
+#ifdef DEBUG_VERBOSE
+ {
+ char *hexp, *asciip;
+ asciip = (lastNamep ? lastNamep : pathp);
+ hexp = osi_HexifyString( asciip );
+ DEBUG_EVENT2("AFS","T2Open H[%s] A[%s]", hexp, asciip);
+ free(hexp);
+ }
+#endif
+
userp = smb_GetTran2User(vcp, p);
+ /* In the off chance that userp is NULL, we log and abandon */
+ if(!userp) {
+ osi_Log1(afsd_logp, "ReceiveTran2Open user [%d] not resolvable", p->uid);
+ smb_FreeTran2Packet(outp);
+ return CM_ERROR_BADSMB;
+ }
+
tidPathp = smb_GetTIDPath(vcp, p->tid);
dscp = NULL;
}
else openAction = 1; /* found existing file */
}
- else if (!(openFun & 0x10)) {
+ else if (!(openFun & SMB_ATTR_DIRECTORY)) {
/* don't create if not found */
if (dscp) cm_ReleaseSCache(dscp);
osi_assert(scp == NULL);
if (extraInfo) {
outp->parmsp[parmSlot] = smb_Attributes(scp); parmSlot++;
smb_SearchTimeFromUnixTime(&dosTime, scp->clientModTime);
- outp->parmsp[parmSlot] = dosTime & 0xffff; parmSlot++;
- outp->parmsp[parmSlot] = (dosTime>>16) & 0xffff; parmSlot++;
+ outp->parmsp[parmSlot] = (unsigned short)(dosTime & 0xffff); parmSlot++;
+ outp->parmsp[parmSlot] = (unsigned short)((dosTime>>16) & 0xffff); parmSlot++;
outp->parmsp[parmSlot] = (unsigned short) (scp->length.LowPart & 0xffff);
parmSlot++;
outp->parmsp[parmSlot] = (unsigned short) ((scp->length.LowPart >> 16) & 0xffff);
case 2:
/* volume info */
- qi.u.volumeInfo.vsn = 1234;
- qi.u.volumeInfo.vnCount = 4;
+ qi.u.volumeInfo.vsn = 1234;
+ qi.u.volumeInfo.vnCount = 4;
/* we're supposed to pad it out with zeroes to the end */
memset(&qi.u.volumeInfo.label, 0, sizeof(qi.u.volumeInfo.label));
- strcpy(qi.u.volumeInfo.label, "AFS");
+ memcpy(qi.u.volumeInfo.label, "AFS", 4);
break;
case 0x102:
/* FS volume info */
memset((char *)&qi.u.FSvolumeInfo.vct, 0, sizeof(FILETIME));
qi.u.FSvolumeInfo.vsn = 1234;
- qi.u.FSvolumeInfo.vnCount = 4;
- strcpy(qi.u.FSvolumeInfo.label, "AFS");
+ qi.u.FSvolumeInfo.vnCount = 8;
+ memcpy(qi.u.FSvolumeInfo.label, "A\0F\0S\0\0", 8);
break;
case 0x103:
}
userp = smb_GetTran2User(vcp, p);
+ if(!userp) {
+ osi_Log1(afsd_logp, "ReceiveTran2QPathInfo unable to resolve user [%d]", p->uid);
+ smb_FreeTran2Packet(outp);
+ return CM_ERROR_BADSMB;
+ }
tidPathp = smb_GetTIDPath(vcp, p->tid);
smb_StripLastComponent(spacep->data, &lastComp,
(char *)(&p->parmsp[3]));
/* Make sure that lastComp is not NULL */
- if (lastComp)
+ if (lastComp) {
if (strcmp(lastComp, "\\desktop.ini") == 0) {
- code = cm_NameI(cm_rootSCachep, spacep->data,
- CM_FLAG_CASEFOLD
- | CM_FLAG_DIRSEARCH
- | CM_FLAG_FOLLOW,
- userp, tidPathp, &req, &dscp);
- if (code == 0) {
- if (dscp->fileType == CM_SCACHETYPE_MOUNTPOINT
- && !dscp->mountRootFidp)
- code = CM_ERROR_NOSUCHFILE;
- else if (dscp->fileType == CM_SCACHETYPE_DIRECTORY) {
- cm_buf_t *bp = buf_Find(dscp, &hzero);
- if (bp)
- buf_Release(bp);
- else
- code = CM_ERROR_NOSUCHFILE;
- }
- cm_ReleaseSCache(dscp);
- if (code) {
- cm_FreeSpace(spacep);
- cm_ReleaseUser(userp);
- smb_SendTran2Error(vcp, p, opx, code);
- smb_FreeTran2Packet(outp);
- return 0;
- }
- }
- }
+ code = cm_NameI(cm_rootSCachep, spacep->data,
+ CM_FLAG_CASEFOLD
+ | CM_FLAG_DIRSEARCH
+ | CM_FLAG_FOLLOW,
+ userp, tidPathp, &req, &dscp);
+ if (code == 0) {
+ if (dscp->fileType == CM_SCACHETYPE_MOUNTPOINT
+ && !dscp->mountRootFidp)
+ code = CM_ERROR_NOSUCHFILE;
+ else if (dscp->fileType == CM_SCACHETYPE_DIRECTORY) {
+ cm_buf_t *bp = buf_Find(dscp, &hzero);
+ if (bp)
+ buf_Release(bp);
+ else
+ code = CM_ERROR_NOSUCHFILE;
+ }
+ cm_ReleaseSCache(dscp);
+ if (code) {
+ cm_FreeSpace(spacep);
+ cm_ReleaseUser(userp);
+ smb_SendTran2Error(vcp, p, opx, code);
+ smb_FreeTran2Packet(outp);
+ return 0;
+ }
+ }
+ }
+ }
cm_FreeSpace(spacep);
}
outp->totalData = nbytesRequired;
userp = smb_GetTran2User(vcp, p);
+ if(!userp) {
+ osi_Log1(afsd_logp, "ReceiveTran2QFileInfo unable to resolve user [%d]", p->uid);
+ code = CM_ERROR_BADSMB;
+ goto done;
+ }
scp = fidp->scp;
lock_ObtainMutex(&scp->mx);
outp->totalData = 0;
userp = smb_GetTran2User(vcp, p);
+ if(!userp) {
+ osi_Log1(afsd_logp,"ReceiveTran2SetFileInfo unable to resolve user [%d]", p->uid);
+ code = CM_ERROR_BADSMB;
+ goto done;
+ }
scp = fidp->scp;
attr.mask = 0;
lastMod = *((FILETIME *)(p->datap + 16));
- /* when called as result of move a b, lastMod is (-1, -1). If the check for -1 is not present, timestamp
- of the resulting file will be 1969 (-1)
+ /* when called as result of move a b, lastMod is (-1, -1).
+ * If the check for -1 is not present, timestamp
+ * of the resulting file will be 1969 (-1)
*/
- if (LargeIntegerNotEqualToZero(*((LARGE_INTEGER *)&lastMod)) && lastMod.dwLowDateTime != -1 && lastMod.dwHighDateTime != -1) {
+ if (LargeIntegerNotEqualToZero(*((LARGE_INTEGER *)&lastMod)) &&
+ lastMod.dwLowDateTime != -1 && lastMod.dwHighDateTime != -1) {
attr.mask |= CM_ATTRMASK_CLIENTMODTIME;
smb_UnixTimeFromLargeSearchTime(&attr.clientModTime,
&lastMod);
/* Copy attributes */
lattr = smb_ExtAttributes(scp);
*((u_long *)dptr) = lattr;
+ /* merge in hidden (dot file) attribute */
+ if( patchp->flags & SMB_DIRLISTPATCH_DOTFILE )
+ lattr |= SMB_ATTR_HIDDEN;
dptr += 4;
}
else {
/* finally copy out attributes as short */
attr = smb_Attributes(scp);
+ /* merge in hidden (dot file) attribute */
+ if( patchp->flags & SMB_DIRLISTPATCH_DOTFILE )
+ attr |= SMB_ATTR_HIDDEN;
*dptr++ = attr & 0xff;
*dptr++ = (attr >> 8) & 0xff;
}
osi_LogSaveString(afsd_logp, pathp));
/* bail out if request looks bad */
- if (p->opcode == 1 && !pathp) {
- return CM_ERROR_BADSMB;
- }
+ if (p->opcode == 1 && !pathp) {
+ smb_ReleaseDirSearch(dsp);
+ smb_FreeTran2Packet(outp);
+ return CM_ERROR_BADSMB;
+ }
osi_Log2(afsd_logp, "T2 dir search cookie 0x%x, connection %d",
nextCookie, dsp->cookie);
- userp = smb_GetTran2User(vcp, p);
+ userp = smb_GetTran2User(vcp, p);
+ if (!userp) {
+ osi_Log1(afsd_logp, "T2 dir search unable to resolve user [%d]", p->uid);
+ smb_ReleaseDirSearch(dsp);
+ smb_FreeTran2Packet(outp);
+ return CM_ERROR_BADSMB;
+ }
/* try to get the vnode for the path name next */
lock_ObtainMutex(&dsp->mx);
curOffset.LowPart &= ~(2048-1);
curOffset.LowPart |= temp;
- /* check if we've returned all the names that will fit in the
- * response packet; we check return count as well as the number
- * of bytes requested. We check the # of bytes after we find
- * the dir entry, since we'll need to check its size.
- */
- if (returnedNames >= maxCount) break;
+ /* check if we've passed the dir's EOF */
+ if (LargeIntegerGreaterThanOrEqualTo(curOffset, dirLength)) {
+ eos = 1;
+ break;
+ }
+
+ /* check if we've returned all the names that will fit in the
+ * response packet; we check return count as well as the number
+ * of bytes requested. We check the # of bytes after we find
+ * the dir entry, since we'll need to check its size.
+ */
+ if (returnedNames >= maxCount) {
+ break;
+ }
- /* check if we've passed the dir's EOF */
- if (LargeIntegerGreaterThanOrEqualTo(curOffset, dirLength)) {
- eos = 1;
- break;
- }
-
- /* see if we can use the bufferp we have now; compute in which
- * page the current offset would be, and check whether that's
- * the offset of the buffer we have. If not, get the buffer.
- */
- thyper.HighPart = curOffset.HighPart;
- thyper.LowPart = curOffset.LowPart & ~(buf_bufferSize-1);
- if (!bufferp || !LargeIntegerEqualTo(thyper, bufferOffset)) {
+ /* see if we can use the bufferp we have now; compute in which
+ * page the current offset would be, and check whether that's
+ * the offset of the buffer we have. If not, get the buffer.
+ */
+ thyper.HighPart = curOffset.HighPart;
+ thyper.LowPart = curOffset.LowPart & ~(buf_bufferSize-1);
+ if (!bufferp || !LargeIntegerEqualTo(thyper, bufferOffset)) {
/* wrong buffer */
- if (bufferp) {
- buf_Release(bufferp);
- bufferp = NULL;
- }
+ if (bufferp) {
+ buf_Release(bufferp);
+ bufferp = NULL;
+ }
lock_ReleaseMutex(&scp->mx);
lock_ObtainRead(&scp->bufCreateLock);
code = buf_Get(scp, &thyper, &bufferp);
/* Eliminate entries that don't match requested
attributes */
- if (!(dsp->attribute & 0x10)) /* no directories */
- {
+ if (smb_hideDotFiles && !(dsp->attribute & SMB_ATTR_HIDDEN) &&
+ smb_IsDotFile(dep->name))
+ goto nextEntry; /* no hidden files */
+
+ if (!(dsp->attribute & SMB_ATTR_DIRECTORY)) /* no directories */
+ {
/* We have already done the cm_TryBulkStat above */
fid.cell = scp->fid.cell;
fid.volume = scp->fid.volume;
curPatchp->dptr = op;
if (infoLevel >= 0x101)
curPatchp->dptr += 8;
+
+ if (smb_hideDotFiles && smb_IsDotFile(dep->name)) {
+ curPatchp->flags = SMB_DIRLISTPATCH_DOTFILE;
+ }
+ else
+ curPatchp->flags = 0;
+
curPatchp->fid.cell = scp->fid.cell;
curPatchp->fid.volume = scp->fid.volume;
curPatchp->fid.vnode = ntohl(dep->fid.vnode);
if (lastNamep && strcmp(lastNamep, SMB_IOCTL_FILENAME) == 0) {
/* special case magic file name for receiving IOCTL requests
- * (since IOCTL calls themselves aren't getting through).
- */
+ * (since IOCTL calls themselves aren't getting through).
+ */
+#ifdef NOTSERVICE
+ osi_Log0(afsd_logp, "IOCTL Open");
+#endif
+
fidp = smb_FindFID(vcp, 0, SMB_FLAG_CREATE);
smb_SetupIoctlFid(fidp, spacep);
return 0;
}
- userp = smb_GetUser(vcp, inp);
+#ifdef DEBUG_VERBOSE
+ {
+ char *hexp, *asciip;
+ asciip = (lastNamep ? lastNamep : pathp );
+ hexp = osi_HexifyString(asciip);
+ DEBUG_EVENT2("AFS", "V3Open H[%s] A[%s]", hexp, asciip );
+ free(hexp);
+ }
+#endif
+ userp = smb_GetUser(vcp, inp);
dscp = NULL;
tidPathp = smb_GetTIDPath(vcp, ((smb_t *)inp)->tid);
if (searchTime != 0) {
smb_UnixTimeFromSearchTime(&unixTime, searchTime);
+
+ if ( unixTime != -1 ) {
attrs.mask = CM_ATTRMASK_CLIENTMODTIME;
attrs.clientModTime = unixTime;
code = cm_SetAttr(scp, &attrs, userp, &req);
+
+ osi_Log1(afsd_logp, "SMB receive V3SetAttributes [fid=%ld]", fid);
+ } else {
+ osi_Log1(afsd_logp, "**smb_UnixTimeFromSearchTime failed searchTime=%ld", searchTime);
+ }
}
else code = 0;
cm_scache_t *scp; /* file to create or open */
cm_attr_t setAttr;
char *lastNamep;
+ char *treeStartp;
unsigned short nameLength;
unsigned int flags;
unsigned int requestOpLock;
unsigned int requestBatchOpLock;
unsigned int mustBeDir;
+ unsigned int treeCreate;
int realDirFlag;
unsigned int desiredAccess;
unsigned int extAttributes;
cm_InitReq(&req);
+ treeCreate = FALSE;
foundscp = FALSE;
scp = NULL;
spacep = inp->spacep;
smb_StripLastComponent(spacep->data, &lastNamep, realPathp);
+ osi_Log1(afsd_logp,"NTCreateX for [%s]",osi_LogSaveString(afsd_logp,realPathp));
+ osi_Log4(afsd_logp,"NTCreateX da=[%x] ea=[%x] cd=[%x] co=[%x]", desiredAccess, extAttributes, createDisp, createOptions);
+
if (lastNamep && strcmp(lastNamep, SMB_IOCTL_FILENAME) == 0) {
/* special case magic file name for receiving IOCTL requests
* (since IOCTL calls themselves aren't getting through).
return 0;
}
- userp = smb_GetUser(vcp, inp);
+#ifdef DEBUG_VERBOSE
+ {
+ char *hexp, *asciip;
+ asciip = (lastNamep? lastNamep : realPathp);
+ hexp = osi_HexifyString( asciip );
+ DEBUG_EVENT2("AFS", "NTCreateX H[%s] A[%s]", hexp, asciip);
+ free(hexp);
+ }
+#endif
+ userp = smb_GetUser(vcp, inp);
+ if (!userp) {
+ osi_Log1(afsd_logp, "NTCreateX Invalid user [%d]", ((smb_t *) inp)->uid);
+ free(realPathp);
+ return CM_ERROR_INVAL;
+ }
if (baseFid == 0) {
baseDirp = cm_rootSCachep;
tidPathp = smb_GetTIDPath(vcp, ((smb_t *)inp)->tid);
}
else {
- baseFidp = smb_FindFID(vcp, baseFid, 0);
+ baseFidp = smb_FindFID(vcp, baseFid, 0);
+ if (!baseFidp) {
+ osi_Log1(afsd_logp, "NTCreateX Invalid base fid [%d]", baseFid);
+ free(realPathp);
+ cm_ReleaseUser(userp);
+ return CM_ERROR_INVAL;
+ }
baseDirp = baseFidp->scp;
tidPathp = NULL;
}
- /* compute open mode */
+ osi_Log1(afsd_logp, "NTCreateX tidPathp=[%s]", (tidPathp==NULL)?"null": osi_LogSaveString(afsd_logp,tidPathp));
+
+ /* compute open mode */
fidflags = 0;
if (desiredAccess & DELETE)
fidflags |= SMB_FID_OPENDELETE;
if (code != 0
|| (fidflags & (SMB_FID_OPENDELETE | SMB_FID_OPENWRITE))) {
/* look up parent directory */
- code = cm_NameI(baseDirp, spacep->data,
- CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD | CM_FLAG_CHECKPATH,
- userp, tidPathp, &req, &dscp);
+ /* If we are trying to create a path (i.e. multiple nested directories), then we don't *need*
+ the immediate parent. We have to work our way up realPathp until we hit something that we
+ recognize.
+ */
+
+ while(1) {
+ char *tp;
+
+ code = cm_NameI(baseDirp, spacep->data,
+ CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD,
+ userp, tidPathp, &req, &dscp);
+
+ if(code &&
+ (tp = strrchr(spacep->data,'\\')) &&
+ (createDisp == 2) &&
+ (realDirFlag == 1)) {
+ *tp++ = 0;
+ treeCreate = TRUE;
+ treeStartp = realPathp + (tp - spacep->data);
+
+ if(*tp && !smb_IsLegalFilename(tp)) {
+ if(baseFid != 0) smb_ReleaseFID(baseFidp);
+ cm_ReleaseUser(userp);
+ free(realPathp);
+ return CM_ERROR_BADNTFILENAME;
+ }
+ }
+ else
+ break;
+ }
- if (baseFid != 0) smb_ReleaseFID(baseFidp);
+ if (baseFid != 0) smb_ReleaseFID(baseFidp);
- if (code) {
- cm_ReleaseUser(userp);
- free(realPathp);
- return code;
- }
+ if (code) {
+ osi_Log0(afsd_logp,"NTCreateX parent not found");
+ cm_ReleaseUser(userp);
+ free(realPathp);
+ return code;
+ }
- if (!lastNamep) lastNamep = realPathp;
- else lastNamep++;
+ if(treeCreate && dscp->fileType == CM_SCACHETYPE_FILE) {
+ /* A file exists where we want a directory. */
+ cm_ReleaseSCache(dscp);
+ cm_ReleaseUser(userp);
+ free(realPathp);
+ return CM_ERROR_EXISTS;
+ }
- if (!smb_IsLegalFilename(lastNamep))
- return CM_ERROR_BADNTFILENAME;
+ if (!lastNamep) lastNamep = realPathp;
+ else lastNamep++;
- if (!foundscp) {
+ if (!smb_IsLegalFilename(lastNamep)) {
+ cm_ReleaseSCache(dscp);
+ cm_ReleaseUser(userp);
+ free(realPathp);
+ return CM_ERROR_BADNTFILENAME;
+ }
+
+ if (!foundscp && !treeCreate) {
code = cm_Lookup(dscp, lastNamep,
CM_FLAG_FOLLOW | CM_FLAG_CASEFOLD,
userp, &req, &scp);
* by dscp, or we may have found the file directly. If code is non-zero,
* scp is NULL.
*/
- if (code == 0) {
+ if (code == 0 && !treeCreate) {
code = cm_CheckNTOpen(scp, desiredAccess, createDisp, userp,
&req);
if (code) {
}
}
else {
- /* create directory */
- osi_assert(dscp != NULL);
- osi_Log1(afsd_logp, "smb_ReceiveNTCreateX creating directory %s",
- osi_LogSaveString(afsd_logp, lastNamep));
+ char *tp, *pp;
+ char *cp; /* This component */
+ int clen; /* length of component */
+ cm_scache_t *tscp;
+ int isLast = 0;
+
+ /* create directory */
+ if ( !treeCreate ) treeStartp = lastNamep;
+ osi_assert(dscp != NULL);
+ osi_Log1(afsd_logp, "smb_ReceiveNTCreateX creating directory [%s]",
+ osi_LogSaveString(afsd_logp, treeStartp));
openAction = 2; /* created directory */
+
setAttr.mask = CM_ATTRMASK_CLIENTMODTIME;
setAttr.clientModTime = time(NULL);
- code = cm_MakeDir(dscp, lastNamep, 0, &setAttr, userp, &req);
- if (code == 0 && (dscp->flags & CM_SCACHEFLAG_ANYWATCH))
- smb_NotifyChange(FILE_ACTION_ADDED,
- FILE_NOTIFY_CHANGE_DIR_NAME,
- dscp, lastNamep, NULL, TRUE);
- if (code == 0
- || (code == CM_ERROR_EXISTS && createDisp != 2)) {
- /* Not an exclusive create, and someone else tried
- * creating it already, then we open it anyway. We
- * don't bother retrying after this, since if this next
- * fails, that means that the file was deleted after we
- * started this call.
- */
- code = cm_Lookup(dscp, lastNamep, CM_FLAG_CASEFOLD,
- userp, &req, &scp);
+
+ pp = treeStartp;
+ cp = spacep->data;
+ tscp = dscp;
+
+ while(pp && *pp) {
+ tp = strchr(pp, '\\');
+ if(!tp) {
+ strcpy(cp,pp);
+ isLast = 1; /* indicate last component. the supplied path never ends in a slash */
+ }
+ else {
+ clen = tp - pp;
+ strncpy(cp,pp,clen);
+ *(cp + clen) = 0;
+ tp++;
+ }
+ pp = tp;
+
+ if(clen == 0) continue; /* the supplied path can't have consecutive slashes either , but */
+
+ /* cp is the next component to be created. */
+ code = cm_MakeDir(tscp, cp, 0, &setAttr, userp, &req);
+ if (code == 0 && (tscp->flags & CM_SCACHEFLAG_ANYWATCH))
+ smb_NotifyChange(FILE_ACTION_ADDED,
+ FILE_NOTIFY_CHANGE_DIR_NAME,
+ tscp, cp, NULL, TRUE);
+ if (code == 0 ||
+ (code == CM_ERROR_EXISTS && createDisp != 2)) {
+ /* Not an exclusive create, and someone else tried
+ * creating it already, then we open it anyway. We
+ * don't bother retrying after this, since if this next
+ * fails, that means that the file was deleted after we
+ * started this call.
+ */
+ code = cm_Lookup(tscp, cp, CM_FLAG_CASEFOLD,
+ userp, &req, &scp);
+ }
+ if(code) break;
+
+ if(!isLast) { /* for anything other than dscp, release it unless it's the last one */
+ cm_ReleaseSCache(tscp);
+ tscp = scp; /* Newly created directory will be next parent */
+ }
}
+
+ /*
+ if we get here and code == 0, then scp is the last directory created, and tscp is the
+ parent of scp. dscp got released if dscp != tscp. both tscp and scp are held.
+ */
+ dscp = tscp;
}
if (code) {
/* something went wrong creating or truncating the file */
if (scp) cm_ReleaseSCache(scp);
+ if (dscp) cm_ReleaseSCache(dscp);
cm_ReleaseUser(userp);
free(realPathp);
return code;
}
- /* make sure we have file vs. dir right */
+ /* make sure we have file vs. dir right (only applies for single component case) */
if (realDirFlag == 0 && scp->fileType != CM_SCACHETYPE_FILE) {
cm_ReleaseSCache(scp);
+ if (dscp) cm_ReleaseSCache(dscp);
cm_ReleaseUser(userp);
free(realPathp);
return CM_ERROR_ISDIR;
}
+ /* (only applies to single component case) */
if (realDirFlag == 1 && scp->fileType == CM_SCACHETYPE_FILE) {
cm_ReleaseSCache(scp);
+ if (dscp) cm_ReleaseSCache(dscp);
cm_ReleaseUser(userp);
free(realPathp);
return CM_ERROR_NOTDIR;
cm_ReleaseUser(userp);
+ /* Can't free realPathp if we get here since fidp->NTopen_wholepathp is pointing there */
+
/* leave scp held since we put it in fidp->scp */
return 0;
}
unsigned int requestOpLock;
unsigned int requestBatchOpLock;
unsigned int mustBeDir;
+ unsigned int extendedRespRequired;
int realDirFlag;
unsigned int desiredAccess;
+#ifdef DEBUG_VERBOSE
+ unsigned int allocSize;
+ unsigned int shareAccess;
+#endif
unsigned int extAttributes;
unsigned int createDisp;
+#ifdef DEBUG_VERBOSE
+ unsigned int sdLen;
+#endif
unsigned int createOptions;
int initialModeBits;
unsigned short baseFid;
requestOpLock = flags & 0x02;
requestBatchOpLock = flags & 0x04;
mustBeDir = flags & 0x08;
+ extendedRespRequired = flags & 0x10;
+
/*
* Why all of a sudden 32-bit FID?
* We will reject all bits higher than 16.
return CM_ERROR_INVAL;
baseFid = (unsigned short)lparmp[1];
desiredAccess = lparmp[2];
+#ifdef DEBUG_VERBOSE
+ allocSize = lparmp[3];
+#endif /* DEBUG_VERSOSE */
extAttributes = lparmp[5];
+#ifdef DEBUG_VEROSE
+ shareAccess = lparmp[6];
+#endif
createDisp = lparmp[7];
createOptions = lparmp[8];
+#ifdef DEBUG_VERBOSE
+ sdLen = lparmp[9];
+#endif
nameLength = lparmp[11];
+#ifdef DEBUG_VERBOSE
+ osi_Log4(afsd_logp,"NTTransCreate with da[%x],ea[%x],sa[%x],cd[%x]",desiredAccess,extAttributes,shareAccess,createDisp);
+ osi_Log2(afsd_logp,"... co[%x],sdl[%x],as[%x]",createOptions,sdLen,allocSize);
+ osi_Log1(afsd_logp,"... flags[%x]",flags);
+#endif
+
/* mustBeDir is never set; createOptions directory bit seems to be
* more important
*/
* Will add it if necessary.
*/
+#ifdef DEBUG_VERBOSE
+ {
+ char *hexp, *asciip;
+ asciip = (lastNamep? lastNamep : realPathp);
+ hexp = osi_HexifyString( asciip );
+ DEBUG_EVENT2("AFS", "NTTranCreate H[%s] A[%s]", hexp, asciip);
+ free(hexp);
+ }
+#endif
+
userp = smb_GetUser(vcp, inp);
+ if(!userp) {
+ osi_Log1(afsd_logp, "NTTranCreate invalid user [%d]", ((smb_t *) inp)->uid);
+ free(realPathp);
+ return CM_ERROR_INVAL;
+ }
if (baseFid == 0) {
baseDirp = cm_rootSCachep;
tidPathp = smb_GetTIDPath(vcp, ((smb_t *)inp)->tid);
}
else {
- baseFidp = smb_FindFID(vcp, baseFid, 0);
+ baseFidp = smb_FindFID(vcp, baseFid, 0);
+ if(!baseFidp) {
+ osi_Log1(afsd_logp, "NTTranCreate Invalid fid [%d]", baseFid);
+ free(realPathp);
+ cm_ReleaseUser(userp);
+ return CM_ERROR_INVAL;
+ }
baseDirp = baseFidp->scp;
tidPathp = NULL;
}
/* set inp->fid so that later read calls in same msg can find fid */
inp->fid = fidp->fid;
- /* out parms */
- parmOffset = 8*4 + 39;
- parmOffset += 1; /* pad to 4 */
- dataOffset = parmOffset + 70;
+ /* check whether we are required to send an extended response */
+ if (!extendedRespRequired) {
+ /* out parms */
+ parmOffset = 8*4 + 39;
+ parmOffset += 1; /* pad to 4 */
+ dataOffset = parmOffset + 70;
+
+ parmSlot = 1;
+ outp->oddByte = 1;
+ /* Total Parameter Count */
+ smb_SetSMBParmLong(outp, parmSlot, 70); parmSlot += 2;
+ /* Total Data Count */
+ smb_SetSMBParmLong(outp, parmSlot, 0); parmSlot += 2;
+ /* Parameter Count */
+ smb_SetSMBParmLong(outp, parmSlot, 70); parmSlot += 2;
+ /* Parameter Offset */
+ smb_SetSMBParmLong(outp, parmSlot, parmOffset); parmSlot += 2;
+ /* Parameter Displacement */
+ smb_SetSMBParmLong(outp, parmSlot, 0); parmSlot += 2;
+ /* Data Count */
+ smb_SetSMBParmLong(outp, parmSlot, 0); parmSlot += 2;
+ /* Data Offset */
+ smb_SetSMBParmLong(outp, parmSlot, dataOffset); parmSlot += 2;
+ /* Data Displacement */
+ smb_SetSMBParmLong(outp, parmSlot, 0); parmSlot += 2;
+ smb_SetSMBParmByte(outp, parmSlot, 0); /* Setup Count */
+ smb_SetSMBDataLength(outp, 70);
- parmSlot = 1;
- outp->oddByte = 1;
- /* Total Parameter Count */
- smb_SetSMBParmLong(outp, parmSlot, 70); parmSlot += 2;
- /* Total Data Count */
- smb_SetSMBParmLong(outp, parmSlot, 0); parmSlot += 2;
- /* Parameter Count */
- smb_SetSMBParmLong(outp, parmSlot, 70); parmSlot += 2;
- /* Parameter Offset */
- smb_SetSMBParmLong(outp, parmSlot, parmOffset); parmSlot += 2;
- /* Parameter Displacement */
- smb_SetSMBParmLong(outp, parmSlot, 0); parmSlot += 2;
- /* Data Count */
- smb_SetSMBParmLong(outp, parmSlot, 0); parmSlot += 2;
- /* Data Offset */
- smb_SetSMBParmLong(outp, parmSlot, dataOffset); parmSlot += 2;
- /* Data Displacement */
- smb_SetSMBParmLong(outp, parmSlot, 0); parmSlot += 2;
- smb_SetSMBParmByte(outp, parmSlot, 0); /* Setup Count */
- smb_SetSMBDataLength(outp, 70);
-
- lock_ObtainMutex(&scp->mx);
- outData = smb_GetSMBData(outp, NULL);
- outData++; /* round to get to parmOffset */
- *outData = 0; outData++; /* oplock */
- *outData = 0; outData++; /* reserved */
- *((USHORT *)outData) = fidp->fid; outData += 2; /* fid */
- *((ULONG *)outData) = openAction; outData += 4;
- *((ULONG *)outData) = 0; outData += 4; /* EA error offset */
- smb_LargeSearchTimeFromUnixTime(&ft, scp->clientModTime);
- *((FILETIME *)outData) = ft; outData += 8; /* creation time */
- *((FILETIME *)outData) = ft; outData += 8; /* last access time */
- *((FILETIME *)outData) = ft; outData += 8; /* last write time */
- *((FILETIME *)outData) = ft; outData += 8; /* change time */
- *((ULONG *)outData) = smb_ExtAttributes(scp); outData += 4;
- *((LARGE_INTEGER *)outData) = scp->length; outData += 8; /* alloc sz */
- *((LARGE_INTEGER *)outData) = scp->length; outData += 8; /* EOF */
- *((USHORT *)outData) = 0; outData += 2; /* filetype */
- *((USHORT *)outData) = 0; outData += 2; /* dev state */
- *((USHORT *)outData) = (scp->fileType == CM_SCACHETYPE_DIRECTORY);
- outData += 2; /* is a dir? */
- lock_ReleaseMutex(&scp->mx);
+ lock_ObtainMutex(&scp->mx);
+ outData = smb_GetSMBData(outp, NULL);
+ outData++; /* round to get to parmOffset */
+ *outData = 0; outData++; /* oplock */
+ *outData = 0; outData++; /* reserved */
+ *((USHORT *)outData) = fidp->fid; outData += 2; /* fid */
+ *((ULONG *)outData) = openAction; outData += 4;
+ *((ULONG *)outData) = 0; outData += 4; /* EA error offset */
+ smb_LargeSearchTimeFromUnixTime(&ft, scp->clientModTime);
+ *((FILETIME *)outData) = ft; outData += 8; /* creation time */
+ *((FILETIME *)outData) = ft; outData += 8; /* last access time */
+ *((FILETIME *)outData) = ft; outData += 8; /* last write time */
+ *((FILETIME *)outData) = ft; outData += 8; /* change time */
+ *((ULONG *)outData) = smb_ExtAttributes(scp); outData += 4;
+ *((LARGE_INTEGER *)outData) = scp->length; outData += 8; /* alloc sz */
+ *((LARGE_INTEGER *)outData) = scp->length; outData += 8; /* EOF */
+ *((USHORT *)outData) = 0; outData += 2; /* filetype */
+ *((USHORT *)outData) = 0; outData += 2; /* dev state */
+ *((USHORT *)outData) = (scp->fileType == CM_SCACHETYPE_DIRECTORY);
+ outData += 2; /* is a dir? */
+ lock_ReleaseMutex(&scp->mx);
+ } else {
+ /* out parms */
+ parmOffset = 8*4 + 39;
+ parmOffset += 1; /* pad to 4 */
+ dataOffset = parmOffset + 104;
+
+ parmSlot = 1;
+ outp->oddByte = 1;
+ /* Total Parameter Count */
+ smb_SetSMBParmLong(outp, parmSlot, 101); parmSlot += 2;
+ /* Total Data Count */
+ smb_SetSMBParmLong(outp, parmSlot, 0); parmSlot += 2;
+ /* Parameter Count */
+ smb_SetSMBParmLong(outp, parmSlot, 101); parmSlot += 2;
+ /* Parameter Offset */
+ smb_SetSMBParmLong(outp, parmSlot, parmOffset); parmSlot += 2;
+ /* Parameter Displacement */
+ smb_SetSMBParmLong(outp, parmSlot, 0); parmSlot += 2;
+ /* Data Count */
+ smb_SetSMBParmLong(outp, parmSlot, 0); parmSlot += 2;
+ /* Data Offset */
+ smb_SetSMBParmLong(outp, parmSlot, dataOffset); parmSlot += 2;
+ /* Data Displacement */
+ smb_SetSMBParmLong(outp, parmSlot, 0); parmSlot += 2;
+ smb_SetSMBParmByte(outp, parmSlot, 0); /* Setup Count */
+ smb_SetSMBDataLength(outp, 105);
+
+ lock_ObtainMutex(&scp->mx);
+ outData = smb_GetSMBData(outp, NULL);
+ outData++; /* round to get to parmOffset */
+ *outData = 0; outData++; /* oplock */
+ *outData = 1; outData++; /* response type */
+ *((USHORT *)outData) = fidp->fid; outData += 2; /* fid */
+ *((ULONG *)outData) = openAction; outData += 4;
+ *((ULONG *)outData) = 0; outData += 4; /* EA error offset */
+ smb_LargeSearchTimeFromUnixTime(&ft, scp->clientModTime);
+ *((FILETIME *)outData) = ft; outData += 8; /* creation time */
+ *((FILETIME *)outData) = ft; outData += 8; /* last access time */
+ *((FILETIME *)outData) = ft; outData += 8; /* last write time */
+ *((FILETIME *)outData) = ft; outData += 8; /* change time */
+ *((ULONG *)outData) = smb_ExtAttributes(scp); outData += 4;
+ *((LARGE_INTEGER *)outData) = scp->length; outData += 8; /* alloc sz */
+ *((LARGE_INTEGER *)outData) = scp->length; outData += 8; /* EOF */
+ *((USHORT *)outData) = 0; outData += 2; /* filetype */
+ *((USHORT *)outData) = 0; outData += 2; /* dev state */
+ *((USHORT *)outData) = (scp->fileType == CM_SCACHETYPE_DIRECTORY);
+ outData += 1; /* is a dir? */
+ memset(outData,0,24); outData += 24; /* Volume ID and file ID */
+ *((ULONG *)outData) = 0x001f01ffL; outData += 4; /* Maxmimal access rights */
+ *((ULONG *)outData) = 0; outData += 4; /* Guest Access rights */
+ lock_ReleaseMutex(&scp->mx);
+ }
osi_Log1(afsd_logp, "SMB NTTranCreate opening fid %d", fidp->fid);
cm_ReleaseUser(userp);
+ /* free(realPathp); Can't free realPathp here because fidp->NTopen_wholepathp points there */
/* leave scp held since we put it in fidp->scp */
return 0;
}
filter = smb_GetSMBParm(inp, 19)
| (smb_GetSMBParm(inp, 20) << 16);
fid = smb_GetSMBParm(inp, 21);
- watchtree = smb_GetSMBParm(inp, 22) && 0xffff;
+ watchtree = smb_GetSMBParm(inp, 22) && 0xffff; /* TODO: should this be 0xff ? */
+
+ fidp = smb_FindFID(vcp, fid, 0);
+ if (!fidp) {
+ osi_Log1(afsd_logp, "ERROR: NotifyChange given invalid fid [%d]", fid);
+ return CM_ERROR_BADFD;
+ }
savedPacketp = smb_CopyPacket(inp);
- savedPacketp->vcp = vcp;
+ savedPacketp->vcp = vcp; /* TODO: refcount vcp? */
lock_ObtainMutex(&smb_Dir_Watch_Lock);
savedPacketp->nextp = smb_Directory_Watches;
smb_Directory_Watches = savedPacketp;
filter = smb_GetSMBParm(watch, 19)
| (smb_GetSMBParm(watch, 20) << 16);
fid = smb_GetSMBParm(watch, 21);
- wtree = smb_GetSMBParm(watch, 22) & 0xffff;
+ wtree = smb_GetSMBParm(watch, 22) & 0xffff; /* TODO: should this be 0xff ? */
maxLen = smb_GetSMBOffsetParm(watch, 5, 1)
| (smb_GetSMBOffsetParm(watch, 6, 1) << 16);
vcp = watch->vcp;
filter = 0x17;
fidp = smb_FindFID(vcp, fid, 0);
+ if (!fidp) {
+ lastWatch = watch;
+ watch = watch->nextp;
+ continue;
+ }
if (fidp->scp != dscp
|| (filter & notifyFilter) == 0
|| (!isDirectParent && !wtree)) {
watchtree = smb_GetSMBParm(watch, 22) & 0xffff;
fidp = smb_FindFID(vcp, fid, 0);
-
- osi_Log3(afsd_logp, "Cancelling change notification for fid %d wtree %d file %s",
- fid, watchtree,
- osi_LogSaveString(afsd_logp, (fidp)?fidp->NTopen_wholepathp:""));
-
- scp = fidp->scp;
- lock_ObtainMutex(&scp->mx);
- if (watchtree)
- scp->flags &= ~CM_SCACHEFLAG_WATCHEDSUBTREE;
- else
- scp->flags &= ~CM_SCACHEFLAG_WATCHED;
- lock_ReleaseMutex(&scp->mx);
- smb_ReleaseFID(fidp);
+ if (fidp) {
+ osi_Log3(afsd_logp, "Cancelling change notification for fid %d wtree %d file %s",
+ fid, watchtree,
+ osi_LogSaveString(afsd_logp, (fidp)?fidp->NTopen_wholepathp:""));
+
+ scp = fidp->scp;
+ lock_ObtainMutex(&scp->mx);
+ if (watchtree)
+ scp->flags &= ~CM_SCACHEFLAG_WATCHEDSUBTREE;
+ else
+ scp->flags &= ~CM_SCACHEFLAG_WATCHED;
+ lock_ReleaseMutex(&scp->mx);
+ smb_ReleaseFID(fidp);
+ } else {
+ osi_Log2(afsd_logp,"NTCancel unable to resolve fid [%d] in vcp[%x]", fid,vcp);
+ }
/* assume STATUS32; return 0xC0000120 (CANCELED) */
replyWctp = watch->wctp;
cm_user_t *smb_FindCMUserByName(/*smb_vc_t *vcp,*/ char *usern, char *machine)
{
- cm_user_t *userp;
/*int newUid;*/
smb_username_t *unp;
op = smb_GetSMBData(outp, NULL);
*op++ = 1;
- *op++ = count & 0xff;
- *op++ = (count >> 8) & 0xff;
+ *op++ = (char)(count & 0xff);
+ *op++ = (char)((count >> 8) & 0xff);
/* now copy the data into the response packet */
memcpy(op, iop->outCopied + iop->outAllocp, count);
osi_Log1(afsd_logp, "Ioctl no uid user %x no name",
userp);
}
- smb_ReleaseUID(uidp);
+ if (uidp) smb_ReleaseUID(uidp);
}
iop->tidPathp = smb_GetTIDPath(vcp, ((smb_t *)inp)->tid);
osi_Log3(afsd_logp, "Ioctl uid %d user %x name %s",
uidp->userID, userp,
osi_LogSaveString(afsd_logp, uidp->unp->name));
- else
+ else if (uidp)
osi_Log2(afsd_logp, "Ioctl uid %d user %x no name",
uidp->userID, userp);
- smb_ReleaseUID(uidp);
+ else
+ osi_Log1(afsd_logp, "Ioctl no uid user %x no name",
+ userp);
+ if (uidp) smb_ReleaseUID(uidp);
}
iop->tidPathp = smb_GetTIDPath(vcp, ((smb_t *)inp)->tid);
############################################################################
# Definitions for generating versioninfo resource via RC
-$(OUT)\afscfg_stub.res: AFS_component_version_number.h
+$(OUT)\afscfg_stub.res:afscfg_stub.rc AFS_component_version_number.h
############################################################################
# Install target; primary makefile target
lang::
$(CD) lang
- for /f %l in ('dir /B ??_??') do @$(NTLANG) %l $(MAKECMD) /nologo /f NTMakefile install
+ for /f %l in ('dir /B ??_??') do @$(NTLANG) %l $(MAKECMD) /nologo /e /f NTMakefile install
$(CD) ..
############################################################################
# Definitions for generating versioninfo resource via RC
-$(OUT)\afssvrcpa_stub.res: AFS_component_version_number.h
+$(OUT)\afssvrcpa_stub.res: afssvrcpa_stub.rc AFS_component_version_number.h
############################################################################
# Install target; primary makefile target
lang::
$(CD) lang
- for /f %l in ('dir /B ??_??') do @$(NTLANG) %l $(MAKECMD) /nologo /f NTMakefile install
+ for /f %l in ('dir /B ??_??') do @$(NTLANG) %l $(MAKECMD) /nologo /e /f NTMakefile install
$(CD) ..
# include the AFSD source tree on our inclusion path
-AFSDEV_AUXCDEFINES = $(AFSDEV_AUXCDEFINES) -I..\afsd
+AFSDEV_AUXCDEFINES = $(AFSDEV_AUXCDEFINES) /D"_AFXDLL" -I..\afsd
# include the primary makefile
RELDIR=WINNT\client_config
$(OUT)\dlg_diag.obj \
$(OUT)\dlg_misc.obj \
$(OUT)\isadmin.obj \
- $(OUT)\dlg_automap.obj
+ $(OUT)\dlg_automap.obj \
+ $(OUT)\dlg_binding.obj \
+ $(OUT)\RegistrySupport.obj \
+ $(OUT)\getlana.obj
EXEOBJSc = \
$(OUT)\cellservdb.obj
VCLIBS =\
comctl32.lib \
shell32.lib \
- mpr.lib
+ mpr.lib \
+ netapi32.lib
EXELIBS = \
$(DESTDIR)\lib\afs\TaLocale.lib \
en_US:
$(CD) lang
- $(NTLANG) $@ $(MAKECMD) /nologo /f NTMakefile install
+ $(NTLANG) $@ $(MAKECMD) /nologo /e /f NTMakefile install
$(CD) ..
ja_JP:
$(CD) lang
- @$(NTLANG) $@ $(MAKECMD) /nologo /f NTMakefile install
+ @$(NTLANG) $@ $(MAKECMD) /nologo /e /f NTMakefile install
$(CD) ..
ko_KR:
$(CD) lang
- @$(NTLANG) $@ $(MAKECMD) /nologo /f NTMakefile install
+ @$(NTLANG) $@ $(MAKECMD) /nologo /e /f NTMakefile install
$(CD) ..
zh_CN:
$(CD) lang
- @$(NTLANG) $@ $(MAKECMD) /nologo /f NTMakefile install
+ @$(NTLANG) $@ $(MAKECMD) /nologo /e /f NTMakefile install
$(CD) ..
zh_TW:
$(CD) lang
- @$(NTLANG) $@ $(MAKECMD) /nologo /f NTMakefile install
+ @$(NTLANG) $@ $(MAKECMD) /nologo /e /f NTMakefile install
$(CD) ..
pt_BR:
$(CD) lang
- @$(NTLANG) $@ $(MAKECMD) /nologo /f NTMakefile install
+ @$(NTLANG) $@ $(MAKECMD) /nologo /e /f NTMakefile install
$(CD) ..
es_ES:
$(CD) lang
- @$(NTLANG) $@ $(MAKECMD) /nologo /f NTMakefile install
+ @$(NTLANG) $@ $(MAKECMD) /nologo /e /f NTMakefile install
$(CD) ..
de_DE:
$(CD) lang
- @$(NTLANG) $@ $(MAKECMD) /nologo /f NTMakefile install
+ @$(NTLANG) $@ $(MAKECMD) /nologo /e /f NTMakefile install
$(CD) ..
-$(OUT)\afs_config_stub.res : AFS_component_version_number.h
+$(OUT)\afs_config_stub.res : afs_config_stub.rc AFS_component_version_number.h
clean::
$(DEL) $(COPYHEADERS)
$(CD) lang
- if exist $(NTLANG) $(NTLANG) en_US $(MAKECMD) /nologo /f NTMakefile clean
- if exist $(NTLANG) $(NTLANG) ja_JP $(MAKECMD) /nologo /f NTMakefile clean
- if exist $(NTLANG) $(NTLANG) ko_KR $(MAKECMD) /nologo /f NTMakefile clean
- if exist $(NTLANG) $(NTLANG) zh_CN $(MAKECMD) /nologo /f NTMakefile clean
- if exist $(NTLANG) $(NTLANG) zh_TW $(MAKECMD) /nologo /f NTMakefile clean
- if exist $(NTLANG) $(NTLANG) pt_BR $(MAKECMD) /nologo /f NTMakefile clean
- if exist $(NTLANG) $(NTLANG) es_ES $(MAKECMD) /nologo /f NTMakefile clean
- if exist $(NTLANG) $(NTLANG) de_DE $(MAKECMD) /nologo /f NTMakefile clean
+ if exist $(NTLANG) $(NTLANG) en_US $(MAKECMD) /nologo /e /f NTMakefile clean
+ if exist $(NTLANG) $(NTLANG) ja_JP $(MAKECMD) /nologo /e /f NTMakefile clean
+ if exist $(NTLANG) $(NTLANG) ko_KR $(MAKECMD) /nologo /e /f NTMakefile clean
+ if exist $(NTLANG) $(NTLANG) zh_CN $(MAKECMD) /nologo /e /f NTMakefile clean
+ if exist $(NTLANG) $(NTLANG) zh_TW $(MAKECMD) /nologo /e /f NTMakefile clean
+ if exist $(NTLANG) $(NTLANG) pt_BR $(MAKECMD) /nologo /e /f NTMakefile clean
+ if exist $(NTLANG) $(NTLANG) es_ES $(MAKECMD) /nologo /e /f NTMakefile clean
+ if exist $(NTLANG) $(NTLANG) de_DE $(MAKECMD) /nologo /e /f NTMakefile clean
$(CD) ..
mkdir:
-mkdir $(OUT)\lang
cd lang
- nmake /nologo /f ntmakefile SRC=$(SRC) OBJ=$(OBJ) mkdir
+ nmake /nologo /e /f ntmakefile SRC=$(SRC) OBJ=$(OBJ) mkdir
cd ..
--- /dev/null
+/*det
+ * Configuration Read/Modify Functions ________________________________________
+ *
+ * Temporarily these just modify the local Registry.
+ * In the near future, they will modify the Registry on the
+ * gateway, if a gateway is being used.
+ *
+ */
+
+#include <windows.h>
+#include <tchar.h>
+//#include <ctype.h>
+#include <stdlib.h>
+#include <drivemap.h>
+
+BOOL Config_ReadString (LPCTSTR pszLHS, LPTSTR pszRHS, size_t cchMax);
+
+extern TCHAR AFSConfigKeyName[] = TEXT("SYSTEM\\CurrentControlSet\\Services\\TransarcAFSDaemon\\Parameters");
+
+void Config_GetGlobalDriveList (DRIVEMAPLIST *pDriveList)
+{
+ // Read the GlobalAutoMapper registry key
+ TCHAR szDriveToMapTo[5];
+ DWORD dwResult;
+ TCHAR szKeyName[256];
+ HKEY hKey;
+ DWORD dwIndex = 0;
+ DWORD dwDriveSize;
+ DWORD dwSubMountSize;
+ TCHAR szSubMount[256];
+ DWORD dwType;
+
+ if (!pDriveList)
+ return;
+
+ memset(pDriveList, 0, sizeof(DRIVEMAPLIST));
+
+ lstrcpy(szKeyName, AFSConfigKeyName);
+ lstrcat(szKeyName, TEXT("\\GlobalAutoMapper"));
+
+ dwResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE, szKeyName, 0, KEY_QUERY_VALUE, &hKey);
+ if (dwResult != ERROR_SUCCESS)
+ return;
+
+ // Get the drive map list so we can lookup the paths that go with our submounts
+ DRIVEMAPLIST DriveMapList;
+ memset(&DriveMapList, 0, sizeof(DRIVEMAPLIST));
+ QueryDriveMapList (&DriveMapList);
+
+ while (1) {
+ dwDriveSize = sizeof(szDriveToMapTo);
+ dwSubMountSize = sizeof(szSubMount);
+
+ dwResult = RegEnumValue(hKey, dwIndex++, szDriveToMapTo, &dwDriveSize, 0, &dwType, (BYTE*)szSubMount, &dwSubMountSize);
+ if (dwResult != ERROR_SUCCESS)
+ break;
+
+ szDriveToMapTo[0] = _totupper(szDriveToMapTo[0]);
+
+ int nCurDrive = szDriveToMapTo[0] - TEXT('A');
+
+ pDriveList->aDriveMap[nCurDrive].chDrive = szDriveToMapTo[0];
+ lstrcpy(pDriveList->aDriveMap[nCurDrive].szSubmount, szSubMount);
+
+ // Find the path that goes with this submount
+ SubmountToPath (&DriveMapList, pDriveList->aDriveMap[nCurDrive].szMapping, szSubMount, FALSE);
+ }
+
+ FreeDriveMapList(&DriveMapList);
+
+ RegCloseKey(hKey);
+}
+
+BOOL Config_ReadNum (LPCTSTR pszLHS, DWORD *pdwRHS)
+{
+ HKEY hk;
+ if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, AFSConfigKeyName, 0, KEY_QUERY_VALUE, &hk) != ERROR_SUCCESS)
+ return FALSE;
+
+ DWORD dwSize = sizeof(*pdwRHS);
+ if (RegQueryValueEx (hk, pszLHS, NULL, NULL, (PBYTE)pdwRHS, &dwSize) != ERROR_SUCCESS)
+ {
+ RegCloseKey (hk);
+ return FALSE;
+ }
+
+ RegCloseKey (hk);
+ return TRUE;
+}
+
+
+BOOL Config_ReadString (LPCTSTR pszLHS, LPTSTR pszRHS, size_t cchMax)
+{
+ HKEY hk;
+ if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, AFSConfigKeyName, 0, KEY_QUERY_VALUE, &hk) != ERROR_SUCCESS)
+ return FALSE;
+
+ DWORD dwSize = sizeof(TCHAR) * cchMax;
+ if (RegQueryValueEx (hk, pszLHS, NULL, NULL, (PBYTE)pszRHS, &dwSize) != ERROR_SUCCESS)
+ {
+ RegCloseKey (hk);
+ return FALSE;
+ }
+
+ RegCloseKey (hk);
+ return TRUE;
+}
+
+
+void Config_WriteNum (LPCTSTR pszLHS, DWORD dwRHS)
+{
+ HKEY hk;
+ DWORD dwDisp;
+ if (RegCreateKeyEx (HKEY_LOCAL_MACHINE, AFSConfigKeyName, 0, TEXT("container"), 0, KEY_SET_VALUE, NULL, &hk, &dwDisp) == ERROR_SUCCESS)
+ {
+ RegSetValueEx (hk, pszLHS, NULL, REG_DWORD, (PBYTE)&dwRHS, sizeof(dwRHS));
+ RegCloseKey (hk);
+ }
+}
+
+
+void Config_WriteString (LPCTSTR pszLHS, LPCTSTR pszRHS)
+{
+ HKEY hk;
+ DWORD dwDisp;
+ if (RegCreateKeyEx (HKEY_LOCAL_MACHINE, AFSConfigKeyName, 0, TEXT("container"), 0, KEY_SET_VALUE, NULL, &hk, &dwDisp) == ERROR_SUCCESS)
+ {
+ RegSetValueEx (hk, pszLHS, NULL, REG_SZ, (PBYTE)pszRHS, sizeof(TCHAR) * (1+lstrlen(pszRHS)));
+ RegCloseKey (hk);
+ }
+}
+
return TRUE;
}
-void Config_GetGlobalDriveList (DRIVEMAPLIST *pDriveList)
-{
- // Read the GlobalAutoMapper registry key
- TCHAR szDriveToMapTo[5];
- DWORD dwResult;
- TCHAR szKeyName[256];
- HKEY hKey;
- DWORD dwIndex = 0;
- DWORD dwDriveSize;
- DWORD dwSubMountSize;
- TCHAR szSubMount[256];
- DWORD dwType;
-
- if (!pDriveList)
- return;
-
- memset(pDriveList, 0, sizeof(DRIVEMAPLIST));
-
- lstrcpy(szKeyName, AFSConfigKeyName);
- lstrcat(szKeyName, TEXT("\\GlobalAutoMapper"));
-
- dwResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE, szKeyName, 0, KEY_QUERY_VALUE, &hKey);
- if (dwResult != ERROR_SUCCESS)
- return;
-
- // Get the drive map list so we can lookup the paths that go with our submounts
- DRIVEMAPLIST DriveMapList;
- memset(&DriveMapList, 0, sizeof(DRIVEMAPLIST));
- QueryDriveMapList (&DriveMapList);
-
- while (1) {
- dwDriveSize = sizeof(szDriveToMapTo);
- dwSubMountSize = sizeof(szSubMount);
-
- dwResult = RegEnumValue(hKey, dwIndex++, szDriveToMapTo, &dwDriveSize, 0, &dwType, (BYTE*)szSubMount, &dwSubMountSize);
- if (dwResult != ERROR_SUCCESS)
- break;
-
- szDriveToMapTo[0] = _totupper(szDriveToMapTo[0]);
-
- int nCurDrive = szDriveToMapTo[0] - TEXT('A');
-
- pDriveList->aDriveMap[nCurDrive].chDrive = szDriveToMapTo[0];
- lstrcpy(pDriveList->aDriveMap[nCurDrive].szSubmount, szSubMount);
-
- // Find the path that goes with this submount
- SubmountToPath (&DriveMapList, pDriveList->aDriveMap[nCurDrive].szMapping, szSubMount, FALSE);
- }
-
- FreeDriveMapList(&DriveMapList);
-
- RegCloseKey(hKey);
-}
-
-
-/*
- * Configuration Read/Modify Functions ________________________________________
- *
- * Temporarily these just modify the local Registry.
- * In the near future, they will modify the Registry on the
- * gateway, if a gateway is being used.
- *
- */
-
-BOOL Config_ReadNum (LPCTSTR pszLHS, DWORD *pdwRHS)
-{
- HKEY hk;
- if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, AFSConfigKeyName, 0, KEY_QUERY_VALUE, &hk) != ERROR_SUCCESS)
- return FALSE;
-
- DWORD dwSize = sizeof(*pdwRHS);
- if (RegQueryValueEx (hk, pszLHS, NULL, NULL, (PBYTE)pdwRHS, &dwSize) != ERROR_SUCCESS)
- {
- RegCloseKey (hk);
- return FALSE;
- }
-
- RegCloseKey (hk);
- return TRUE;
-}
-
-
-BOOL Config_ReadString (LPCTSTR pszLHS, LPTSTR pszRHS, size_t cchMax)
-{
- HKEY hk;
- if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, AFSConfigKeyName, 0, KEY_QUERY_VALUE, &hk) != ERROR_SUCCESS)
- return FALSE;
-
- DWORD dwSize = sizeof(TCHAR) * cchMax;
- if (RegQueryValueEx (hk, pszLHS, NULL, NULL, (PBYTE)pszRHS, &dwSize) != ERROR_SUCCESS)
- {
- RegCloseKey (hk);
- return FALSE;
- }
-
- RegCloseKey (hk);
- return TRUE;
-}
-
-
-void Config_WriteNum (LPCTSTR pszLHS, DWORD dwRHS)
-{
- HKEY hk;
- DWORD dwDisp;
- if (RegCreateKeyEx (HKEY_LOCAL_MACHINE, AFSConfigKeyName, 0, TEXT("container"), 0, KEY_SET_VALUE, NULL, &hk, &dwDisp) == ERROR_SUCCESS)
- {
- RegSetValueEx (hk, pszLHS, NULL, REG_DWORD, (PBYTE)&dwRHS, sizeof(dwRHS));
- RegCloseKey (hk);
- }
-}
-
-
-void Config_WriteString (LPCTSTR pszLHS, LPCTSTR pszRHS)
-{
- HKEY hk;
- DWORD dwDisp;
- if (RegCreateKeyEx (HKEY_LOCAL_MACHINE, AFSConfigKeyName, 0, TEXT("container"), 0, KEY_SET_VALUE, NULL, &hk, &dwDisp) == ERROR_SUCCESS)
- {
- RegSetValueEx (hk, pszLHS, NULL, REG_SZ, (PBYTE)pszRHS, sizeof(TCHAR) * (1+lstrlen(pszRHS)));
- RegCloseKey (hk);
- }
-}
-
* PROTOTYPES _________________________________________________________________
*
*/
+extern void GetNetbiosName(LPTSTR pszName, int type);
void AutoMap_OnInitDialog (HWND hDlg);
void AutoMap_OnAdd (HWND hDlg);
SendMessage (hCombo, CB_SETCURSEL, iItemSel, 0);
TCHAR szMapping[ MAX_PATH ];
+#ifdef NOLANA
AdjustAfsPath (szMapping, ((pMap->szMapping[0]) ? pMap->szMapping : cm_slash_mount_root), TRUE, FALSE);
+#else
+ memset(szMapping, '\0', sizeof(szMapping));
+ szMapping[0] = '\\';
+ GetNetbiosName(&szMapping[1], 0);
+#endif
SetDlgItemText (hDlg, IDC_PATH, szMapping);
SetDlgItemText (hDlg, IDC_DESC, pMap->szSubmount);
return;
}
- if ( (lstrncmpi (pMap->szMapping, cm_slash_mount_root, lstrlen(cm_slash_mount_root))) &&
- (lstrncmpi (pMap->szMapping, cm_back_slash_mount_root, lstrlen(cm_back_slash_mount_root))) )
+#ifdef NOLANA
+ if ( (lstrncmpi (pMap->szMapping, cm_slash_mount_root, lstrlen(cm_slash_mount_root))) &&
+ (lstrncmpi (pMap->szMapping, cm_back_slash_mount_root, lstrlen(cm_back_slash_mount_root))) )
+ {
+ Message (MB_ICONHAND, GetErrorTitle(), IDS_BADMAP_DESC);
+ return;
+ }
+#else
+ TCHAR szName[MAX_PATH];
+ memset(szName, '\0', sizeof(szName));
+ szName[0] = '\\';
+ GetNetbiosName(&szName[1], 0);
+
+ if ( lstrncmpi (pMap->szMapping, szName, lstrlen(szName) ))
{
Message (MB_ICONHAND, GetErrorTitle(), IDS_BADMAP_DESC);
return;
}
+#endif
// First get a proper submount
if (pMap->szSubmount[0]) {
--- /dev/null
+/*
+ * Copyright 2000, International Business Machines Corporation and others.
+ * All Rights Reserved.
+ *
+ * This software has been released under the terms of the IBM Public
+ * License. For details, see the LICENSE file in the top-level source
+ * directory or online at http://www.openafs.org/dl/license10.html
+ */
+
+extern "C" {
+#include <afs/param.h>
+#include <afs/stds.h>
+}
+#include <stdio.h>
+#include "afs_config.h"
+#include "getlana.h"
+
+
+/*
+ * DEFINITIONS ________________________________________________________________
+ *
+ */
+
+
+// Our dialog data
+static BOOL fFirstTime = TRUE;
+int nLanAdapter;
+LANAINFO* lanainfo = NULL;
+
+int GetAdapterNumber(TCHAR*);
+
+/*
+ * PROTOTYPES _________________________________________________________________
+ *
+ */
+
+void Binding_OnInitDialog (HWND hDlg);
+void Binding_OnOK(HWND hDlg);
+void Binding_OnCancel(HWND hDlg);
+BOOL Binding_OnApply();
+
+BOOL isGateway = FALSE;
+/*
+ * ROUTINES ___________________________________________________________________
+ *
+ */
+
+BOOL CALLBACK Binding_DlgProc (HWND hDlg, UINT msg, WPARAM wp, LPARAM lp)
+{
+ switch (msg)
+ {
+ case WM_INITDIALOG:
+ Binding_OnInitDialog (hDlg);
+ break;
+
+ case WM_CTLCOLORSTATIC:
+ if ((HWND)lp == GetDlgItem (hDlg, IDC_CHUNK_SIZE))
+ {
+ if (IsWindowEnabled ((HWND)lp))
+ {
+ static HBRUSH hbrStatic = CreateSolidBrush (GetSysColor (COLOR_WINDOW));
+ SetTextColor ((HDC)wp, GetSysColor (COLOR_WINDOWTEXT));
+ SetBkColor ((HDC)wp, GetSysColor (COLOR_WINDOW));
+ return (BOOL)hbrStatic;
+ }
+ }
+ break;
+
+ case WM_COMMAND:
+ switch (LOWORD(wp))
+ {
+ case IDHELP:
+ Binding_DlgProc (hDlg, WM_HELP, 0, 0);
+ break;
+
+ case IDOK:
+ Binding_OnOK(hDlg);
+ break;
+
+ case IDCANCEL:
+ Binding_OnCancel(hDlg);
+ break;
+ case IDC_DEFAULTNIC:
+ if (HIWORD(wp) == BN_CLICKED)
+ {
+ TCHAR name[MAX_PATH];
+ memset(name, 0, sizeof(name));
+ if (IsDlgButtonChecked(hDlg,IDC_DEFAULTNIC))
+ nLanAdapter=-1;
+ else
+ {
+ HWND hwndCombo = GetDlgItem(hDlg, IDC_NICSELECTION);
+ if (SendMessage(hwndCombo, CB_GETCURSEL, 0, 0) == CB_ERR)
+ SendMessage(hwndCombo, CB_SETCURSEL, (WPARAM)0, (LPARAM)0);
+
+ TCHAR selected[MAX_PATH];
+ memset(selected, 0, sizeof(selected));
+ SendDlgItemMessage(hDlg, IDC_NICSELECTION,
+ WM_GETTEXT, sizeof(selected),
+ (LPARAM) selected);
+
+ if (_tcslen(selected) <= 0)
+
+ nLanAdapter = -1;
+ else
+ nLanAdapter = GetAdapterNumber(selected);
+ }
+
+ GetAfsName(nLanAdapter, isGateway, name);
+ SetDlgItemText (hDlg, IDC_BINDING_MESSAGE, name);
+ EnableWindow(GetDlgItem(hDlg,IDC_NICSELECTION),(nLanAdapter!=-1));
+ break;
+ }
+ case IDC_NICSELECTION:
+ if (HIWORD(wp) == CBN_SELCHANGE)
+ {
+ TCHAR name[MAX_PATH];
+ TCHAR selected[MAX_PATH];
+ memset(name, 0, sizeof(name));
+ &nbs