Since 1.3.74:
+ * The afs_config.exe submounts dialog had two errors.
+ First, attempts to remove entries failed because the registry
+ key was being opened without KEY_WRITE privileges.
+ Second, when editing a submount entry, changing the name
+ would add a new key and leave the original one in place.
+ Now the original submount will be removed if its name is
+ changed.
+
+ * In recent months there have been several incidents in which
+ users have experienced problems starting or accessing
+ afsd_service.exe and after significant effort has been spent
+ it has turned out that they have two versions of AFS on the
+ machine or an inconsistent set of DLLs.
+
+ Code has now been added to afsd_service.exe which will walk
+ the list of modules loaded by afsd_service.exe and validate
+ that the version of the AFS DLLs matches the version of the
+ afsd_service.exe executable. If they do not match the service
+ will not start.
+
+ * When Freelance mode is enabled and there is no registry
+ key HKLM\SOFTWARE\OpenAFS\Client\Freelance, afsd_service.exe
+ will attempt to import the afs_freelance.ini file contents.
+ If the file does not exist, it was creating a dummy file
+ with a r/o and r/w entry for the default cell and then
+ importing those values.
+
+ This process has been changed. The temporary file is no
+ longer created. Also, both the OpenAFS Client install
+ directory as well as %WINDIR% are checked for previous
+ afs_freelance.ini files.
+
* Added support for VL_GetEntryByNameN(). Still need to add
support for VL_GetEntryByNameU() for multi-homed support.
those entries which are used are allocated.
+26. "Netbios over TCP/IP" must be active on the machine in order for
+communication with the AFS Client Service to succeed. If "Netbios over
+TCP/IP" is disabled on the machine, then communication with the AFS Client
+Service will be impossible.
+
+
------------------------------------------------------------------------
Reporting Bugs:
directory is used.
+Value : IoctlDebug
+Type : REG_DEBUG
+Default : 0x0
+
+ This value can be used to debug the cause of pioctl() failures.
+ Set a non-zero value and the pioctl() library will output status
+ information to stdout. Executing command line tools such as
+ tokens.exe, fs.exe, etc can then be used to determine why the
+ pioctl() call is failing.
+
+
2.1 Domain specific configuration keys for the Network Provider
---------------------------------------------------------------
clean::
$(CD) lang
- for /f %l in ('dir /B ??_??') do @$(NTLANG) %l $(MAKECMD) /nologo /f NTMakefile clean
+ for /f %l in ('dir /B ??_??') if exist @$(NTLANG) do @$(NTLANG) %l $(MAKECMD) /nologo /f NTMakefile clean
$(CD) ..
AFSD_SDKLIBS =\
largeint.lib \
netapi32.lib \
- dnsapi.lib mpr.lib \
+ dnsapi.lib \
+ mpr.lib \
rpcrt4.lib \
user32.lib \
Dbghelp.lib \
mpr.lib \
secur32.lib \
ole32.lib \
- oleaut32.lib
+ oleaut32.lib \
+ psapi.lib
AFSD_EXELIBS =\
$(DESTDIR)\lib\libosi.lib \
extern initUpperCaseTable();
void afsd_initUpperCaseTable()
{
- initUpperCaseTable();
+ initUpperCaseTable();
}
void
}
SetFilePointer(afsi_file, 0, NULL, FILE_END);
- GetTimeFormat(LOCALE_SYSTEM_DEFAULT, 0, NULL, NULL, u, sizeof(u));
- StringCbCatA(t, sizeof(t), ": Create log file\n");
- StringCbCatA(u, sizeof(u), ": Created log file\n");
- WriteFile(afsi_file, t, strlen(t), &zilch, NULL);
- WriteFile(afsi_file, u, strlen(u), &zilch, NULL);
+ GetTimeFormat(LOCALE_SYSTEM_DEFAULT, 0, NULL, NULL, u, sizeof(u));
+ StringCbCatA(t, sizeof(t), ": Create log file\n");
+ StringCbCatA(u, sizeof(u), ": Created log file\n");
+ WriteFile(afsi_file, t, strlen(t), &zilch, NULL);
+ WriteFile(afsi_file, u, strlen(u), &zilch, NULL);
p = "PATH=";
path = getenv("PATH");
- WriteFile(afsi_file, p, strlen(p), &zilch, NULL);
- WriteFile(afsi_file, path, strlen(path), &zilch, NULL);
- WriteFile(afsi_file, "\n", 1, &zilch, NULL);
+ WriteFile(afsi_file, p, strlen(p), &zilch, NULL);
+ WriteFile(afsi_file, path, strlen(path), &zilch, NULL);
+ WriteFile(afsi_file, "\n", 1, &zilch, NULL);
}
static int afsi_log_useTimestamp = 1;
void
afsi_log(char *pattern, ...)
{
- char s[256], t[100], d[100], u[512];
- int zilch;
- va_list ap;
- va_start(ap, pattern);
+ char s[256], t[100], d[100], u[512];
+ int zilch;
+ va_list ap;
+ va_start(ap, pattern);
- StringCbVPrintfA(s, sizeof(s), pattern, ap);
+ StringCbVPrintfA(s, sizeof(s), pattern, ap);
if ( afsi_log_useTimestamp ) {
GetTimeFormat(LOCALE_SYSTEM_DEFAULT, 0, NULL, NULL, t, sizeof(t));
- GetDateFormat(LOCALE_SYSTEM_DEFAULT, 0, NULL, NULL, d, sizeof(d));
- StringCbPrintfA(u, sizeof(u), "%s %s: %s\n", d, t, s);
+ GetDateFormat(LOCALE_SYSTEM_DEFAULT, 0, NULL, NULL, d, sizeof(d));
+ StringCbPrintfA(u, sizeof(u), "%s %s: %s\n", d, t, s);
if (afsi_file != INVALID_HANDLE_VALUE)
WriteFile(afsi_file, u, strlen(u), &zilch, NULL);
#ifdef NOTSERVICE
void afsd_ForceTrace(BOOL flush)
{
- HANDLE handle;
- int len;
- char buf[256];
+ HANDLE handle;
+ int len;
+ char buf[256];
- if (!logReady)
+ if (!logReady)
return;
- len = GetTempPath(sizeof(buf)-10, buf);
- StringCbCopyA(&buf[len], sizeof(buf)-len, "/afsd.log");
- handle = CreateFile(buf, GENERIC_WRITE, FILE_SHARE_READ,
- NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
- if (handle == INVALID_HANDLE_VALUE) {
- logReady = 0;
- osi_panic("Cannot create log file", __FILE__, __LINE__);
- }
- osi_LogPrint(afsd_logp, handle);
- if (flush)
- FlushFileBuffers(handle);
- CloseHandle(handle);
+ len = GetTempPath(sizeof(buf)-10, buf);
+ StringCbCopyA(&buf[len], sizeof(buf)-len, "/afsd.log");
+ handle = CreateFile(buf, GENERIC_WRITE, FILE_SHARE_READ,
+ NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
+ if (handle == INVALID_HANDLE_VALUE) {
+ logReady = 0;
+ osi_panic("Cannot create log file", __FILE__, __LINE__);
+ }
+ osi_LogPrint(afsd_logp, handle);
+ if (flush)
+ FlushFileBuffers(handle);
+ CloseHandle(handle);
}
static void
int afsd_InitDaemons(char **reasonP)
{
- long code;
- cm_req_t req;
+ long code;
+ cm_req_t req;
- cm_InitReq(&req);
+ cm_InitReq(&req);
- /* this should really be in an init daemon from here on down */
+ /* this should really be in an init daemon from here on down */
if (!cm_freelanceEnabled) {
osi_Log0(afsd_logp, "Loading Root Volume from cell");
}
}
- /* compute the root fid */
- if (!cm_freelanceEnabled) {
+ /* 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;
- }
- else
+ }
+ else
cm_FakeRootFid(&cm_rootFid);
code = cm_GetSCache(&cm_rootFid, &cm_rootSCachep, cm_rootUserp, &req);
- afsi_log("cm_GetSCache code %x scache %x", code,
+ afsi_log("cm_GetSCache code %x scache %x", code,
(code ? (cm_scache_t *)-1 : cm_rootSCachep));
- if (code != 0) {
- *reasonP = "unknown error";
- return -1;
- }
+ if (code != 0) {
+ *reasonP = "unknown error";
+ return -1;
+ }
- cm_InitDaemon(numBkgD);
- afsi_log("cm_InitDaemon");
+ cm_InitDaemon(numBkgD);
+ afsi_log("cm_InitDaemon");
- return 0;
+ return 0;
}
int afsd_InitSMB(char **reasonP, void *aMBfunc)
{
- /* Do this last so that we don't handle requests before init is done.
+ /* Do this last so that we don't handle requests before init is done.
* Here we initialize the SMB listener.
*/
smb_Init(afsd_logp, cm_NetbiosName, smb_UseV3, LANadapter, numSvThreads, aMBfunc);
afsi_log("smb_Init");
- return 0;
+ return 0;
}
#ifdef ReadOnly
#include <afs/stds.h>
#include <windows.h>
+#include <psapi.h>
#include <string.h>
#include <setjmp.h>
#include "afsd.h"
RegCloseKey(hKey);
}
+DWORD
+GetVersionInfo( CHAR * filename, CHAR * szOutput, DWORD dwOutput )
+{
+ DWORD dwVersionHandle;
+ LPVOID pVersionInfo = 0;
+ DWORD retval = 0;
+ LPDWORD pLangInfo = 0;
+ LPTSTR szVersion = 0;
+ UINT len = 0;
+ TCHAR szVerQ[] = TEXT("\\StringFileInfo\\12345678\\FileVersion");
+ DWORD size = GetFileVersionInfoSize(filename, &dwVersionHandle);
+
+ if (!size) {
+ afsi_log("GetFileVersionInfoSize failed");
+ return GetLastError();
+ }
+
+ pVersionInfo = malloc(size);
+ if (!pVersionInfo) {
+ afsi_log("out of memory 1");
+ return ERROR_NOT_ENOUGH_MEMORY;
+ }
+
+ GetFileVersionInfo(filename, dwVersionHandle, size, pVersionInfo);
+ if (retval = GetLastError())
+ {
+ afsi_log("GetFileVersionInfo failed: %d", retval);
+ goto cleanup;
+ }
+
+ VerQueryValue(pVersionInfo, TEXT("\\VarFileInfo\\Translation"),
+ (LPVOID*)&pLangInfo, &len);
+ if (retval = GetLastError())
+ {
+ afsi_log("VerQueryValue 1 failed: %d", retval);
+ goto cleanup;
+ }
+
+ wsprintf(szVerQ,
+ TEXT("\\StringFileInfo\\%04x%04x\\FileVersion"),
+ LOWORD(*pLangInfo), HIWORD(*pLangInfo));
+
+ VerQueryValue(pVersionInfo, szVerQ, (LPVOID*)&szVersion, &len);
+ if (retval = GetLastError())
+ {
+ /* try again with language 409 since the old binaries were tagged wrong */
+ wsprintf(szVerQ,
+ TEXT("\\StringFileInfo\\0409%04x\\FileVersion"),
+ HIWORD(*pLangInfo));
+
+ VerQueryValue(pVersionInfo, szVerQ, (LPVOID*)&szVersion, &len);
+ if (retval = GetLastError()) {
+ afsi_log("VerQueryValue 2 failed: [%s] %d", szVerQ, retval);
+ goto cleanup;
+ }
+ }
+ snprintf(szOutput, dwOutput, TEXT("%s"), szVersion);
+ szOutput[dwOutput - 1] = 0;
+
+ cleanup:
+ if (pVersionInfo)
+ free(pVersionInfo);
+
+ return retval;
+}
+
+
+BOOL AFSModulesVerify(void)
+{
+ CHAR filename[1024];
+ CHAR afsdVersion[128];
+ CHAR modVersion[128];
+ CHAR checkName[1024];
+ HMODULE hMods[1024];
+ HANDLE hProcess;
+ DWORD cbNeeded;
+ unsigned int i;
+ BOOL success = TRUE;
+
+ if (!GetModuleFileName(NULL, filename, sizeof(filename)))
+ return FALSE;
+
+ if (GetVersionInfo(filename, afsdVersion, sizeof(afsdVersion)))
+ return FALSE;
+
+ afsi_log("%s version %s", filename, afsdVersion);
+
+ // Get a list of all the modules in this process.
+ hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
+ FALSE, GetCurrentProcessId());
+
+ if (EnumProcessModules(hProcess, hMods, sizeof(hMods), &cbNeeded))
+ {
+ afsi_log("Num of Process Modules: %d", (cbNeeded / sizeof(HMODULE)));
+
+ for (i = 0; i < (cbNeeded / sizeof(HMODULE)); i++)
+ {
+ char szModName[2048];
+
+ // Get the full path to the module's file.
+ if (GetModuleFileNameEx(hProcess, hMods[i], szModName, sizeof(szModName)))
+ {
+ lstrcpy(checkName, szModName);
+ strlwr(checkName);
+
+ if ( strstr(checkName, "afspthread.dll") ||
+ strstr(checkName, "afsauthent.dll") ||
+ strstr(checkName, "afsrpc.dll") ||
+ strstr(checkName, "libafsconf.dll") ||
+ strstr(checkName, "libosi.dll") )
+ {
+ if (GetVersionInfo(szModName, modVersion, sizeof(modVersion))) {
+ success = FALSE;
+ continue;
+ }
+
+ afsi_log("%s version %s", szModName, modVersion);
+ if (strcmp(afsdVersion,modVersion)) {
+ afsi_log("Version mismatch: %s", szModName);
+ success = FALSE;
+ }
+ }
+ }
+ }
+ }
+
+ CloseHandle(hProcess);
+ return success;
+}
+
typedef BOOL ( APIENTRY * AfsdInitHook )(void);
#define AFSD_INIT_HOOK "AfsdInitHook"
#define AFSD_HOOK_DLL "afsdhook.dll"
}
#endif
+ /* Verify the versions of the DLLs which were loaded */
+ if (!AFSModulesVerify()) {
+ ServiceStatus.dwCurrentState = SERVICE_STOPPED;
+ ServiceStatus.dwWin32ExitCode = NO_ERROR;
+ ServiceStatus.dwCheckPoint = 0;
+ ServiceStatus.dwWaitHint = 0;
+ ServiceStatus.dwControlsAccepted = 0;
+ SetServiceStatus(StatusHandle, &ServiceStatus);
+
+ /* exit if initialization failed */
+ return;
+ }
+
/* allow an exit to be called prior to any initialization */
hInitHookDll = LoadLibrary(AFSD_HOOK_DLL);
if (hInitHookDll)
clean::
$(CD) lang
- for /f %l in ('dir /B ??_??') do @$(NTLANG) %l $(MAKECMD) /nologo /f NTMakefile clean
+ for /f %l in ('dir /B ??_??') if exist @$(NTLANG) do @$(NTLANG) %l $(MAKECMD) /nologo /f NTMakefile clean
$(CD) ..
mkdir:
clean::
$(CD) lang
- for /f %l in ('dir /B ??_??') do @$(NTLANG) %l $(MAKECMD) /nologo /f NTMakefile clean
+ for /f %l in ('dir /B ??_??') if exist @$(NTLANG) do @$(NTLANG) %l $(MAKECMD) /nologo /f NTMakefile clean
$(CD) ..
mkdir:
clean::
$(CD) lang
- for /f %l in ('dir /B ??_??') do @$(NTLANG) %l $(MAKECMD) /nologo /f NTMakefile clean
+ for /f %l in ('dir /B ??_??') if exist @$(NTLANG) do @$(NTLANG) %l $(MAKECMD) /nologo /f NTMakefile clean
$(CD) ..
mkdir:
clean::
$(CD) lang
- for /f %l in ('dir /B ??_??') do @$(NTLANG) %l $(MAKECMD) /nologo /f NTMakefile clean
+ for /f %l in ('dir /B ??_??') if exist @$(NTLANG) do @$(NTLANG) %l $(MAKECMD) /nologo /f NTMakefile clean
$(CD) ..
mkdir:
0,
NULL,
REG_OPTION_NON_VOLATILE,
- KEY_READ,
+ KEY_WRITE,
NULL,
&hkSub,
NULL);
// Action - On Add or On Edit a submount item
void Submounts_EditSubmount (HWND hDlg, PSUBMOUNT pSubmount)
{
- HWND hList = GetDlgItem (hDlg, IDC_LIST);
+ TCHAR szOrigSubmount[MAX_PATH];
+ _tcscpy(szOrigSubmount, pSubmount->szSubmount);
- if (ModalDialogParam (IDD_SUBMOUNT_EDIT, GetParent(hDlg), (DLGPROC)SubEdit_DlgProc, (LPARAM)pSubmount) == IDOK)
- {
- TCHAR szMapping[ MAX_PATH ];
- AdjustAfsPath (szMapping, pSubmount->szMapping, TRUE, FALSE);
+ HWND hList = GetDlgItem (hDlg, IDC_LIST);
- HLISTITEM hItem;
- for (hItem = FastList_FindFirst (hList); hItem; hItem = FastList_FindNext (hList, hItem))
- {
- LPCTSTR pszSubmount;
- if ((pszSubmount = FastList_GetItemText (hList, hItem, 0)) == NULL)
- continue;
+ if (ModalDialogParam (IDD_SUBMOUNT_EDIT, GetParent(hDlg), (DLGPROC)SubEdit_DlgProc, (LPARAM)pSubmount) == IDOK)
+ {
+ TCHAR szMapping[ MAX_PATH ];
+ BOOL bNameChange = (szOrigSubmount[0] && _tcsicmp(szOrigSubmount, pSubmount->szSubmount));
- if (!lstrcmpi (pszSubmount, pSubmount->szSubmount))
- break;
- }
+ AdjustAfsPath (szMapping, pSubmount->szMapping, TRUE, FALSE);
- if (!hItem)
- {
- FASTLISTADDITEM ai;
- memset (&ai, 0x00, sizeof(FASTLISTADDITEM));
- ai.iFirstImage = IMAGE_NOIMAGE;
- ai.iSecondImage = IMAGE_NOIMAGE;
- ai.pszText = pSubmount->szSubmount;
- ai.lParam = 0;
- hItem = FastList_AddItem (hList, &ai);
- }
+ HLISTITEM hItem;
- FastList_SetItemText (hList, hItem, 1, szMapping);
- }
+ if ( bNameChange ) {
+ for (hItem = FastList_FindFirst (hList); hItem; hItem = FastList_FindNext (hList, hItem))
+ {
+ LPCTSTR pszSubmount;
+ if ((pszSubmount = FastList_GetItemText (hList, hItem, 0)) == NULL)
+ continue;
+
+ if (!_tcsicmp(szOrigSubmount, pszSubmount) ) {
+ FastList_RemoveItem (hList, hItem);
+ break;
+ }
+ }
+ }
+
+ for (hItem = FastList_FindFirst (hList); hItem; hItem = FastList_FindNext (hList, hItem))
+ {
+ LPCTSTR pszSubmount;
+ if ((pszSubmount = FastList_GetItemText (hList, hItem, 0)) == NULL)
+ continue;
+
+ if (!_tcsicmp(pszSubmount, pSubmount->szSubmount))
+ break;
+ }
+
+ if (!hItem)
+ {
+ FASTLISTADDITEM ai;
+ memset (&ai, 0x00, sizeof(FASTLISTADDITEM));
+ ai.iFirstImage = IMAGE_NOIMAGE;
+ ai.iSecondImage = IMAGE_NOIMAGE;
+ ai.pszText = pSubmount->szSubmount;
+ ai.lParam = 0;
+ hItem = FastList_AddItem (hList, &ai);
+ }
+
+ FastList_SetItemText (hList, hItem, 1, szMapping);
+ }
}
clean::
$(CD) lang
- for /f %l in ('dir /B ??_??') do @$(NTLANG) %l $(MAKECMD) /nologo /f NTMakefile clean
+ for /f %l in ('dir /B ??_??') if exist @$(NTLANG) do @$(NTLANG) %l $(MAKECMD) /nologo /f NTMakefile clean
$(CD) ..
mkdir:
DLLLIBS =\
rpcndr.lib \
rpcrt4.lib \
- rpcns4.lib \
- largeint.lib
+ rpcns4.lib
+# largeint.lib
$(DLLFILE): $(DLLOBJS)
$(DLLGUILINK) $(DLLLIBS) -def:libosi.def
PTHR_DLLFILE = $(DESTDIR)\lib\afspthread.dll
+$(OUT)\pthread.res: pthread.rc AFS_component_version_number.h
+ $(RC) /fo$*.res $(*F).rc
+
PTHR_DLLOBJS = \
$(OUT)\pthread.obj \
$(OUT)\pthread.res
#define used in WinNT/2000 installation and program version display
AFSPRODUCT_VER_MAJOR=1
AFSPRODUCT_VER_MINOR=3
-AFSPRODUCT_VER_PATCH=7400
+AFSPRODUCT_VER_PATCH=7401
AFSPRODUCT_VER_BUILD=0
# For MSI installer, each major release should have a different GUID
/* Internalname and originalfilename must be specified or explorer won't
show version and description */
BEGIN
- BLOCK "040904E4"
+ BLOCK "000004E4"
BEGIN
VALUE "CompanyName", "OpenAFS Project", "\0"
VALUE "LegalCopyright", "Copyright \251 IBM Corporation and others, 1998, 1999, 2000, 2001, 2002, 2003.", "\0"