afsifs-20050615

Windows IFS client code and build option
This commit is contained in:
Eric Williams 2005-06-15 17:51:44 +00:00 committed by Jim Rees
parent be485c9598
commit 3cc3cedba0
25 changed files with 6345 additions and 23 deletions

View File

@ -13,6 +13,18 @@ prior to Windows 2000 are not being supported. The InstallShield
installer is still in the source tree but is no longer supported.
A new open source installer based on NSIS 2.0 replaces it.
NOTE:
In this release, there are two clients offered: an SMB version (as was
included in all previous versions), and an IFS version (newly released).
To build the IFS version, follow the directions below, but note that
only the NSIS installer script can be correctly configured; the Wix
installer will not work correctly. Also, the kernel module associated
with the IFS version must be built separately, using the IFS kit or DDK
build environment. While in the DDK build environment, enter into the
afsrdr source directory, and execute 'build'. This will create the
module to be packaged by the installer.
*********** Windows 2000/XP/2003 Build Process ****************
Building OpenAFS for Windows requires configuring a Windows
@ -232,7 +244,7 @@ STEP F. Begin the build
(3) Configure the environment variables:
For a release build:
For a release build (SMB version):
(a) Execute the VCVARS32.BAT or VSVARS32.BAT file which part of the
Visual Studio environment you installed.
@ -241,7 +253,16 @@ STEP F. Begin the build
(c) Execute the NTBUILD.BAT file with the parameter "free"
For a debug build:
For a release build (IFS version):
(a) Execute the VCVARS32.BAT or VSVARS32.BAT file which part of the
Visual Studio environment you installed.
(b) Execute the SETENV.BAT file with the parameters "/2000 /RETAIL"
(c) Execute the NTBUILD.BAT file with the parameter "free ifs"
For a debug build (SMB version):
(a) Execute the VCVARS32.BAT or VSVARS32.BAT file which part of the
Visual Studio environment you installed.
@ -250,6 +271,15 @@ STEP F. Begin the build
(c) Execute the NTBUILD.BAT file with the parameter "checked"
For a debug build (IFS version):
(a) Execute the VCVARS32.BAT or VSVARS32.BAT file which part of the
Visual Studio environment you installed.
(b) Execute the SETENV.BAT file with the parameters "/2000 /DEBUG"
(c) Execute the NTBUILD.BAT file with the parameter "checked ifs"
(4) Clean the work area:
nmake /f NTMakefile clean

View File

@ -88,7 +88,15 @@ $(RXOBJS): $(RX)\$$(@B).c
$(IDLFILES):afsrpc.idl
midl $(MIDL_FLAGS) /no_robust $(AFSDEV_AUXMIDLFLAGS) /app_config $?
RPCOBJS = $(OUT)\ifs_rpc.obj
$(RPCOBJS):..\afsrdr\ifs_rpc.c
$(C2OBJ) ..\afsrdr\ifs_rpc.c
AFSDOBJS=\
$(OUT)\ifs_rpc.obj \
$(OUT)\rawops.obj \
$(OUT)\afsdifs.obj \
$(OUT)\afsd_init.obj \
$(OUT)\cm_cell.obj \
$(OUT)\cm_server.obj \

View File

@ -6,6 +6,30 @@
* License. For details, see the LICENSE file in the top-level source
* directory or online at http://www.openafs.org/dl/license10.html
*/
/* copyright (c) 2005
* the regents of the university of michigan
* all rights reserved
*
* permission is granted to use, copy, create derivative works and
* redistribute this software and such derivative works for any purpose,
* so long as the name of the university of michigan is not used in
* any advertising or publicity pertaining to the use or distribution
* of this software without specific, written prior authorization. if
* the above copyright notice or any other identification of the
* university of michigan is included in any copy of any portion of
* this software, then the disclaimer below must also be included.
*
* this software is provided as is, without representation from the
* university of michigan as to its fitness for any purpose, and without
* warranty by the university of michigan of any kind, either express
* or implied, including without limitation the implied warranties of
* merchantability and fitness for a particular purpose. the regents
* of the university of michigan shall not be liable for any damages,
* including special, indirect, incidental, or consequential damages,
* with respect to any claim arising out or in connection with the use
* of the software, even if it has been or is hereafter advised of the
* possibility of such damages.
*/
#include <afs/param.h>
#include <afs/stds.h>
@ -25,12 +49,16 @@
#include <crtdbg.h>
#endif
#include "afsdifs.h"
HANDLE main_inst;
HWND main_wnd;
char main_statusText[100];
RECT main_rect;
osi_log_t *afsd_logp;
HANDLE hAFSDWorkerThread[WORKER_THREADS], DoTerminate;
extern int traceOnPanic;
extern void afsd_DbgBreakAllocInit();
@ -77,6 +105,7 @@ int WINAPI WinMain(
int nCmdShow)
{
MSG msg;
int i;
afsd_SetUnhandledExceptionFilter();
@ -104,6 +133,15 @@ int WINAPI WinMain(
TranslateMessage(&msg);
DispatchMessage(&msg);
}
#ifdef AFSIFS
WaitForMultipleObjects(WORKER_THREADS, hAFSDWorkerThread, TRUE, INFINITE);
for (i = 0; i < WORKER_THREADS; i++)
CloseHandle(hAFSDWorkerThread[i]);
//CloseHandle(hAFSDMainThread);
RpcMgmtStopServerListening(NULL);
#endif
return (msg.wParam);
}
@ -137,7 +175,7 @@ BOOL InitInstance(
HDC hDC;
TEXTMETRIC textmetric;
INT nLineHeight;
long code;
long code, cnt;
char *reason;
/* remember this, since it is a useful thing for some of the Windows
@ -185,10 +223,23 @@ BOOL InitInstance(
if (code != 0)
osi_panic(reason, __FILE__, __LINE__);
code = afsd_InitSMB(&reason, MessageBox);
#ifndef AFSIFS
code = afsd_InitSMB(&reason, MessageBox);
#else
code = ifs_Init(&reason);
#endif
if (code != 0)
osi_panic(reason, __FILE__, __LINE__);
#ifdef AFSIFS
DoTerminate = CreateEvent(NULL, TRUE, FALSE, TEXT("afsd_service_DoTerminate"));
if ( GetLastError() == ERROR_ALREADY_EXISTS )
afsi_log("Event Object Already Exists: %s", TEXT("afsd_service_DoTerminate"));
for (cnt = 0; cnt < WORKER_THREADS; cnt++)
hAFSDWorkerThread[cnt] = CreateThread(NULL, 0, ifs_MainLoop, 0, 0, NULL);
#endif
ShowWindow(hWnd, SW_SHOWMINNOACTIVE);
UpdateWindow(hWnd);
return (TRUE);
@ -225,7 +276,11 @@ LONG APIENTRY MainWndProc(
break;
case WM_DESTROY:
#ifndef AFSIFS
RpcMgmtStopServerListening(NULL);
#else
SetEvent(DoTerminate);
#endif
PostQuitMessage(0);
break;

View File

@ -132,6 +132,8 @@ extern HANDLE WaitToTerminate;
#define LOG_PACKET 1
#undef NOTSERVICE
#define WORKER_THREADS 10
#define AFSD_HOOK_DLL "afsdhook.dll"
#define AFSD_INIT_HOOK "AfsdInitHook"
typedef BOOL ( APIENTRY * AfsdInitHook )(void);

View File

@ -6,6 +6,30 @@
* License. For details, see the LICENSE file in the top-level source
* directory or online at http://www.openafs.org/dl/license10.html
*/
/* copyright (c) 2005
* the regents of the university of michigan
* all rights reserved
*
* permission is granted to use, copy, create derivative works and
* redistribute this software and such derivative works for any purpose,
* so long as the name of the university of michigan is not used in
* any advertising or publicity pertaining to the use or distribution
* of this software without specific, written prior authorization. if
* the above copyright notice or any other identification of the
* university of michigan is included in any copy of any portion of
* this software, then the disclaimer below must also be included.
*
* this software is provided as is, without representation from the
* university of michigan as to its fitness for any purpose, and without
* warranty by the university of michigan of any kind, either express
* or implied, including without limitation the implied warranties of
* merchantability and fitness for a particular purpose. the regents
* of the university of michigan shall not be liable for any damages,
* including special, indirect, incidental, or consequential damages,
* with respect to any claim arising out or in connection with the use
* of the software, even if it has been or is hereafter advised of the
* possibility of such damages.
*/
#include <afs/param.h>
#include <afs/stds.h>
@ -31,6 +55,7 @@
#ifdef _DEBUG
#include <crtdbg.h>
#endif
#include "afsdifs.h"
//#define REGISTER_POWER_NOTIFICATIONS 1
#include "afsd_flushvol.h"
@ -41,8 +66,11 @@ static SERVICE_STATUS ServiceStatus;
static SERVICE_STATUS_HANDLE StatusHandle;
HANDLE hAFSDMainThread = NULL;
#ifdef AFSIFS
HANDLE hAFSDWorkerThread[WORKER_THREADS];
#endif
HANDLE WaitToTerminate;
HANDLE WaitToTerminate, DoTerminate;
int GlobalStatus;
@ -64,6 +92,7 @@ static void afsd_notifier(char *msgp, char *filep, long line)
char tbuffer[512];
char *ptbuf[1];
HANDLE h;
int i;
if (filep)
sprintf(tbuffer, "Error at file %s, line %d: %s",
@ -96,7 +125,14 @@ static void afsd_notifier(char *msgp, char *filep, long line)
DebugBreak();
#endif
SetEvent(WaitToTerminate);
#ifndef AFSIFS
SetEvent(WaitToTerminate);
#else
SetEvent(DoTerminate);
WaitForMultipleObjects(WORKER_THREADS, hAFSDWorkerThread, TRUE, INFINITE);
for (i = 0; i < WORKER_THREADS; i++)
CloseHandle(hAFSDWorkerThread[i]);
#endif
#ifdef JUMP
if (GetCurrentThreadId() == MainThreadId)
@ -201,7 +237,11 @@ afsd_ServiceControlHandler(DWORD ctrlCode)
}
doneTrace:
#ifndef AFSIFS
SetEvent(WaitToTerminate);
#else
SetEvent(DoTerminate);
#endif
break;
case SERVICE_CONTROL_INTERROGATE:
@ -269,7 +309,11 @@ afsd_ServiceControlHandlerEx(
}
doneTrace:
#ifndef AFSIFS
SetEvent(WaitToTerminate);
#else
SetEvent(DoTerminate);
#endif
dwRet = NO_ERROR;
break;
@ -403,6 +447,7 @@ static void MountGlobalDrives(void)
}
}
#ifndef AFSIFS
for ( ; dwRetry < MAX_RETRIES; dwRetry++)
{
NETRESOURCE nr;
@ -429,6 +474,9 @@ static void MountGlobalDrives(void)
/* Disconnect any previous mappings */
dwResult = WNetCancelConnection2(szDriveToMapTo, 0, TRUE);
}
#else
/* FIXFIX */
#endif
}
RegCloseKey(hKey);
@ -453,7 +501,8 @@ static void DismountGlobalDrives()
if (dwResult != ERROR_SUCCESS)
return;
while (1) {
#ifndef AFSIFS
while (1) {
dwDriveSize = sizeof(szDriveToMapTo);
dwSubMountSize = sizeof(szSubMount);
dwResult = RegEnumValue(hKey, dwIndex++, szDriveToMapTo, &dwDriveSize, 0, &dwType, szSubMount, &dwSubMountSize);
@ -472,6 +521,9 @@ static void DismountGlobalDrives()
afsi_log("Disconnect from GlobalAutoMap of %s to %s %s", szDriveToMapTo, szSubMount, dwResult ? "succeeded" : "failed");
}
#else
/* FIXFIX */
#endif
RegCloseKey(hKey);
}
@ -1015,6 +1067,7 @@ afsd_Main(DWORD argc, LPTSTR *argv)
#endif /* JUMP */
HMODULE hHookDll;
HMODULE hAdvApi32;
int cnt;
#ifdef _DEBUG
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF /*| _CRTDBG_CHECK_ALWAYS_DF*/ |
@ -1032,6 +1085,12 @@ afsd_Main(DWORD argc, LPTSTR *argv)
if ( GetLastError() == ERROR_ALREADY_EXISTS )
afsi_log("Event Object Already Exists: %s", TEXT("afsd_service_WaitToTerminate"));
#ifdef AFSIFS
DoTerminate = CreateEvent(NULL, TRUE, FALSE, TEXT("afsd_service_DoTerminate"));
if ( GetLastError() == ERROR_ALREADY_EXISTS )
afsi_log("Event Object Already Exists: %s", TEXT("afsd_service_DoTerminate"));
#endif
#ifndef NOTSERVICE
hAdvApi32 = LoadLibrary("advapi32.dll");
if (hAdvApi32 == NULL)
@ -1207,11 +1266,22 @@ afsd_Main(DWORD argc, LPTSTR *argv)
ServiceStatus.dwWaitHint -= 5000;
SetServiceStatus(StatusHandle, &ServiceStatus);
#endif
#ifndef AFSIFS
code = afsd_InitSMB(&reason, MessageBox);
if (code != 0) {
afsi_log("afsd_InitSMB failed: %s (code = %d)", reason, code);
osi_panic(reason, __FILE__, __LINE__);
}
#else
code = ifs_Init(&reason);
if (code != 0) {
afsi_log("ifs_Init failed: %s (code = %d)", reason, code);
osi_panic(reason, __FILE__, __LINE__);
}
for (cnt = 0; cnt < WORKER_THREADS; cnt++)
hAFSDWorkerThread[cnt] = CreateThread(NULL, 0, ifs_MainLoop, 0, 0, NULL);
#endif
/* allow an exit to be called post smb initialization */
hHookDll = LoadLibrary(AFSD_HOOK_DLL);
@ -1288,7 +1358,13 @@ afsd_Main(DWORD argc, LPTSTR *argv)
}
}
WaitForSingleObject(WaitToTerminate, INFINITE);
#ifndef AFSIFS
WaitForSingleObject(WaitToTerminate, INFINITE);
#else
WaitForMultipleObjects(WORKER_THREADS, hAFSDWorkerThread, TRUE, INFINITE);
for (cnt = 0; cnt < WORKER_THREADS; cnt++)
CloseHandle(hAFSDWorkerThread[cnt]);
#endif
afsi_log("Received Termination Signal, Stopping Service");
@ -1429,7 +1505,11 @@ main(int argc, char * argv[])
printf("Hit <Enter> to terminate OpenAFS Client Service\n");
getchar();
#ifndef AFSIFS
SetEvent(WaitToTerminate);
#else
SetEvent(DoTerminate);
#endif
}
}

1191
src/WINNT/afsd/afsdifs.c Normal file

File diff suppressed because it is too large Load Diff

33
src/WINNT/afsd/afsdifs.h Normal file
View File

@ -0,0 +1,33 @@
/* copyright (c) 2005
* the regents of the university of michigan
* all rights reserved
*
* permission is granted to use, copy, create derivative works and
* redistribute this software and such derivative works for any purpose,
* so long as the name of the university of michigan is not used in
* any advertising or publicity pertaining to the use or distribution
* of this software without specific, written prior authorization. if
* the above copyright notice or any other identification of the
* university of michigan is included in any copy of any portion of
* this software, then the disclaimer below must also be included.
*
* this software is provided as is, without representation from the
* university of michigan as to its fitness for any purpose, and without
* warranty by the university of michigan of any kind, either express
* or implied, including without limitation the implied warranties of
* merchantability and fitness for a particular purpose. the regents
* of the university of michigan shall not be liable for any damages,
* including special, indirect, incidental, or consequential damages,
* with respect to any claim arising out or in connection with the use
* of the software, even if it has been or is hereafter advised of the
* possibility of such damages.
*/
int ifs_Init(char **reason);
DWORD WINAPI ifs_MainLoop(LPVOID);
long ReadData(cm_scache_t *scp, osi_hyper_t offset, long count, char *op,
cm_user_t *userp, long *readp);
long WriteData(cm_scache_t *scp, osi_hyper_t offset, long count, char *op,
cm_user_t *userp, long *readp);

View File

@ -91,6 +91,12 @@ void cm_RecordRacingRevoke(cm_fid_t *fidp, long cancelFlags)
lock_ReleaseWrite(&cm_callbackLock);
}
#ifdef AFSIFS
#define BUF_FILEHASH(fidp) ((((fidp)->vnode+((fidp)->unique << 13) + ((fidp)->unique >> (32-13)) \
+(fidp)->volume+(fidp)->cell) \
/*& 0xffffffff*/))
#endif
/*
* When we lose a callback, may have to send change notification replies.
* Do not call with a lock on the scp.
@ -123,10 +129,14 @@ void cm_CallbackNotifyChange(cm_scache_t *scp)
Sleep(dwDelay);
if (scp->fileType == CM_SCACHETYPE_DIRECTORY) {
#ifndef AFSIFS
if (scp->flags & CM_SCACHEFLAG_ANYWATCH)
smb_NotifyChange(0,
FILE_NOTIFY_GENERIC_DIRECTORY_FILTER,
scp, NULL, NULL, TRUE);
#else
dc_break_callback(BUF_FILEHASH(&scp->fid));
#endif
} else {
cm_fid_t tfid;
cm_scache_t *dscp;
@ -136,11 +146,16 @@ void cm_CallbackNotifyChange(cm_scache_t *scp)
tfid.vnode = scp->parentVnode;
tfid.unique = scp->parentUnique;
dscp = cm_FindSCache(&tfid);
#ifndef AFSIFS
if ( dscp &&
dscp->flags & CM_SCACHEFLAG_ANYWATCH )
smb_NotifyChange( 0,
FILE_NOTIFY_GENERIC_FILE_FILTER,
dscp, NULL, NULL, TRUE);
#else
if (dscp)
dc_break_callback(BUF_FILEHASH(&dscp->fid));
#endif
if (dscp)
cm_ReleaseSCache(dscp);
}

View File

@ -41,6 +41,8 @@
#include "cm_rpc.h"
#include <strsafe.h>
#include <winioctl.h>
#include <WINNT\afsrdr\kif.h>
#ifdef _DEBUG
#include <crtdbg.h>
@ -141,9 +143,11 @@ void TranslateExtendedChars(char *str)
long cm_ParseIoctlPath(smb_ioctl_t *ioctlp, cm_user_t *userp, cm_req_t *reqp,
cm_scache_t **scpp)
{
long code;
long code, length;
cm_scache_t *substRootp;
char * relativePath = ioctlp->inDatap;
char * relativePath = ioctlp->inDatap, absRoot[100];
wchar_t absRoot_w[100];
HANDLE rootDir;
/* This is usually the file name, but for StatMountPoint it is the path. */
/* ioctlp->inDatap can be either of the form:
@ -154,7 +158,47 @@ long cm_ParseIoctlPath(smb_ioctl_t *ioctlp, cm_user_t *userp, cm_req_t *reqp,
*/
TranslateExtendedChars(relativePath);
if (relativePath[0] == relativePath[1] &&
#ifdef AFSIFS
/* we have passed the whole path, including the afs prefix (pioctl_nt.c modified) */
/*_asm int 3;
sprintf(absRoot, "%c:", relativePath[0]);
rootDir = CreateFile(absRoot, 0, 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
if (!DeviceIoControl(rootDir, IOCTL_AFSRDR_GET_PATH, NULL, 0, absRoot_w, 100*sizeof(wchar_t), &length, NULL))
{
CloseHandle(rootDir);
return CM_ERROR_NOSUCHPATH;
}
CloseHandle(rootDir);
ifs_ConvertFileName(absRoot_w, length/sizeof(wchar_t), absRoot, 100);*/
#if 0
switch (relativePath[0]) /* FIXFIX */
{
case 'y':
case 'Y':
absRoot = "\\ericjw\\test"; /* should use drivemap */
}
#endif
code = cm_NameI(cm_data.rootSCachep, relativePath,
CM_FLAG_CASEFOLD | CM_FLAG_FOLLOW,
userp, ""/*absRoot*//*ioctlp->tidPathp*/, reqp, scpp);
if (code)
return code;
/* # of bytes of path */
code = strlen(ioctlp->inDatap) + 1;
ioctlp->inDatap += code;
/* This is usually nothing, but for StatMountPoint it is the file name. */
TranslateExtendedChars(ioctlp->inDatap);
return 0;
#endif
if (relativePath[0] == relativePath[1] &&
relativePath[1] == '\\' &&
!_strnicmp(cm_NetbiosName,relativePath+2,strlen(cm_NetbiosName)))
{
@ -1787,7 +1831,8 @@ long cm_IoctlSetToken(struct smb_ioctl *ioctlp, struct cm_user *userp)
uname = tp;
tp += strlen(tp) + 1;
if (flags & PIOCTL_LOGON) {
#ifndef AFSIFS /* no SMB username */
if (flags & PIOCTL_LOGON) {
/* SMB user name with which to associate tokens */
smbname = tp;
osi_Log2(smb_logp,"cm_IoctlSetToken for user [%s] smbname [%s]",
@ -1798,6 +1843,7 @@ long cm_IoctlSetToken(struct smb_ioctl *ioctlp, struct cm_user *userp)
osi_Log1(smb_logp,"cm_IoctlSetToken for user [%s]",
osi_LogSaveString(smb_logp,uname));
}
#endif
#ifndef DJGPP /* for win95, session key is back in pioctl */
/* uuid */

View File

@ -545,7 +545,20 @@ long cm_ApplyDir(cm_scache_t *scp, cm_DirFuncp_t funcp, void *parmp,
break;
}
lock_ObtainMutex(&bufferp->mx);
#ifdef AFSIFS
lock_ObtainMutex(&scp->mx);
if ((scp->flags & CM_SCACHEFLAG_BULKSTATTING) == 0
&& (scp->bulkStatProgress.QuadPart <= thyper.QuadPart))
{
scp->flags |= CM_SCACHEFLAG_BULKSTATTING;
cm_TryBulkStat(scp, &thyper, userp, reqp);
scp->flags &= ~CM_SCACHEFLAG_BULKSTATTING;
scp->bulkStatProgress = thyper;
}
lock_ReleaseMutex(&scp->mx);
#endif
lock_ObtainMutex(&bufferp->mx);
bufferOffset = thyper;
/* now get the data in the cache */

364
src/WINNT/afsd/rawops.c Normal file
View File

@ -0,0 +1,364 @@
/*
* 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
*/
#include <osi.h>
#include "afsd.h"
#include "afsdifs.h"
#define CM_BUF_SIZE 4096
long buf_bufferSize = CM_BUF_SIZE;
long ReadData(cm_scache_t *scp, osi_hyper_t offset, long count, char *op,
cm_user_t *userp, long *readp)
{
//osi_hyper_t offset;
long code;
cm_buf_t *bufferp;
osi_hyper_t fileLength;
osi_hyper_t thyper;
osi_hyper_t lastByte;
osi_hyper_t bufferOffset;
long bufIndex, nbytes;
int sequential = 0;
cm_req_t req;
cm_InitReq(&req);
bufferp = NULL;
lock_ObtainMutex(&scp->mx);
/* start by looking up the file's end */
code = cm_SyncOp(scp, NULL, userp, &req, 0,
CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
if (code) goto done;
/* now we have the entry locked, look up the length */
fileLength = scp->length;
/* adjust count down so that it won't go past EOF */
thyper.LowPart = count;
thyper.HighPart = 0;
thyper = LargeIntegerAdd(offset, thyper); /* where read should end */
lastByte = thyper;
if (LargeIntegerGreaterThan(thyper, fileLength)) {
/* we'd read past EOF, so just stop at fileLength bytes.
* Start by computing how many bytes remain in the file.
*/
thyper = LargeIntegerSubtract(fileLength, offset);
/* if we are past EOF, read 0 bytes */
if (LargeIntegerLessThanZero(thyper))
count = 0;
else
count = thyper.LowPart;
}
*readp = count;
/* now, copy the data one buffer at a time,
* until we've filled the request packet
*/
while (1) {
/* if we've copied all the data requested, we're done */
if (count <= 0) break;
/* otherwise, load up a buffer of data */
thyper.HighPart = offset.HighPart;
thyper.LowPart = offset.LowPart & ~(buf_bufferSize-1);
if (!bufferp || !LargeIntegerEqualTo(thyper, bufferOffset)) {
/* wrong buffer */
if (bufferp) {
buf_Release(bufferp);
bufferp = NULL;
}
lock_ReleaseMutex(&scp->mx);
lock_ObtainRead(&scp->bufCreateLock);
code = buf_Get(scp, &thyper, &bufferp);
lock_ReleaseRead(&scp->bufCreateLock);
lock_ObtainMutex(&scp->mx);
if (code) goto done;
bufferOffset = thyper;
/* now get the data in the cache */
while (1) {
code = cm_SyncOp(scp, bufferp, userp, &req, 0,
CM_SCACHESYNC_NEEDCALLBACK
| CM_SCACHESYNC_READ);
if (code) goto done;
if (cm_HaveBuffer(scp, bufferp, 0)) break;
/* otherwise, load the buffer and try again */
code = cm_GetBuffer(scp, bufferp, NULL, userp, &req);
if (code) break;
}
if (code) {
buf_Release(bufferp);
bufferp = NULL;
goto done;
}
} /* if (wrong buffer) ... */
/* now we have the right buffer loaded. Copy out the
* data from here to the user's buffer.
*/
bufIndex = offset.LowPart & (buf_bufferSize - 1);
/* and figure out how many bytes we want from this buffer */
nbytes = buf_bufferSize - bufIndex; /* what remains in buffer */
if (nbytes > count) nbytes = count; /* don't go past EOF */
/* now copy the data */
memcpy(op, bufferp->datap + bufIndex, nbytes);
/* adjust counters, pointers, etc. */
op += nbytes;
count -= nbytes;
thyper.LowPart = nbytes;
thyper.HighPart = 0;
offset = LargeIntegerAdd(thyper, offset);
} /* while 1 */
done:
lock_ReleaseMutex(&scp->mx);
//lock_ReleaseMutex(&fidp->mx);
if (bufferp) buf_Release(bufferp);
if (code == 0 && sequential)
cm_ConsiderPrefetch(scp, &lastByte, userp, &req);
return code;
}
long WriteData(cm_scache_t *scp, osi_hyper_t offset, long count, char *op,
cm_user_t *userp, long *writtenp)
{
long code = 0;
long written = 0;
//cm_scache_t *scp;
osi_hyper_t fileLength; /* file's length at start of write */
osi_hyper_t minLength; /* don't read past this */
long nbytes; /* # of bytes to transfer this iteration */
cm_buf_t *bufferp;
osi_hyper_t thyper; /* hyper tmp variable */
osi_hyper_t bufferOffset;
long bufIndex; /* index in buffer where our data is */
int doWriteBack;
osi_hyper_t writeBackOffset; /* offset of region to write back when
* I/O is done */
DWORD filter = 0;
cm_req_t req;
cm_InitReq(&req);
bufferp = NULL;
doWriteBack = 0;
//scp = fidp->scp;
lock_ObtainMutex(&scp->mx);
/* start by looking up the file's end */
code = cm_SyncOp(scp, NULL, userp, &req, 0,
CM_SCACHESYNC_NEEDCALLBACK
| CM_SCACHESYNC_SETSTATUS
| CM_SCACHESYNC_GETSTATUS);
if (code)
goto done;
/* make sure we have a writable FD */
/*if (!(fidp->flags & SMB_FID_OPENWRITE)) {
code = CM_ERROR_BADFDOP;
goto done;
} */
/* now we have the entry locked, look up the length */
fileLength = scp->length;
minLength = fileLength;
if (LargeIntegerGreaterThan(minLength, scp->serverLength))
minLength = scp->serverLength;
/* adjust file length if we extend past EOF */
thyper.LowPart = count;
thyper.HighPart = 0;
thyper = LargeIntegerAdd(offset, thyper); /* where write should end */
if (LargeIntegerGreaterThan(thyper, fileLength)) {
/* we'd write past EOF, so extend the file */
scp->mask |= CM_SCACHEMASK_LENGTH;
scp->length = thyper;
filter |= (FILE_NOTIFY_CHANGE_LAST_WRITE | FILE_NOTIFY_CHANGE_SIZE);
} else
filter |= FILE_NOTIFY_CHANGE_LAST_WRITE;
/* now, if the new position (thyper) and the old (offset) are in
* different storeback windows, remember to store back the previous
* storeback window when we're done with the write.
*/
if ((thyper.LowPart & (-cm_chunkSize)) !=
(offset.LowPart & (-cm_chunkSize))) {
/* they're different */
doWriteBack = 1;
writeBackOffset.HighPart = offset.HighPart;
writeBackOffset.LowPart = offset.LowPart & (-cm_chunkSize);
}
*writtenp = count;
/* now, copy the data one buffer at a time, until we've filled the
* request packet */
while (1) {
/* if we've copied all the data requested, we're done */
if (count <= 0) break;
/* handle over quota or out of space */
if (scp->flags & (CM_SCACHEFLAG_OVERQUOTA | CM_SCACHEFLAG_OUTOFSPACE)) {
*writtenp = written;
break;
}
/* otherwise, load up a buffer of data */
thyper.HighPart = offset.HighPart;
thyper.LowPart = offset.LowPart & ~(buf_bufferSize-1);
if (!bufferp || !LargeIntegerEqualTo(thyper, bufferOffset)) {
/* wrong buffer */
if (bufferp) {
lock_ReleaseMutex(&bufferp->mx);
buf_Release(bufferp);
bufferp = NULL;
}
lock_ReleaseMutex(&scp->mx);
lock_ObtainRead(&scp->bufCreateLock);
code = buf_Get(scp, &thyper, &bufferp);
lock_ReleaseRead(&scp->bufCreateLock);
lock_ObtainMutex(&bufferp->mx);
lock_ObtainMutex(&scp->mx);
if (code) goto done;
bufferOffset = thyper;
/* now get the data in the cache */
while (1) {
code = cm_SyncOp(scp, bufferp, userp, &req, 0,
CM_SCACHESYNC_NEEDCALLBACK
| CM_SCACHESYNC_WRITE
| CM_SCACHESYNC_BUFLOCKED);
if (code)
goto done;
/* If we're overwriting the entire buffer, or
* if we're writing at or past EOF, mark the
* buffer as current so we don't call
* cm_GetBuffer. This skips the fetch from the
* server in those cases where we're going to
* obliterate all the data in the buffer anyway,
* or in those cases where there is no useful
* data at the server to start with.
*
* Use minLength instead of scp->length, since
* the latter has already been updated by this
* call.
*/
if (LargeIntegerGreaterThanOrEqualTo(bufferp->offset, minLength) ||
LargeIntegerEqualTo(offset, bufferp->offset) &&
(count >= buf_bufferSize ||
LargeIntegerGreaterThanOrEqualTo(LargeIntegerAdd(offset, ConvertLongToLargeInteger(count)), minLength))) {
if (count < buf_bufferSize
&& bufferp->dataVersion == -1)
memset(bufferp->datap, 0,
buf_bufferSize);
bufferp->dataVersion = scp->dataVersion;
}
if (cm_HaveBuffer(scp, bufferp, 1)) break;
/* otherwise, load the buffer and try again */
lock_ReleaseMutex(&bufferp->mx);
code = cm_GetBuffer(scp, bufferp, NULL, userp,
&req);
lock_ReleaseMutex(&scp->mx);
lock_ObtainMutex(&bufferp->mx);
lock_ObtainMutex(&scp->mx);
if (code) break;
}
if (code) {
lock_ReleaseMutex(&bufferp->mx);
buf_Release(bufferp);
bufferp = NULL;
goto done;
}
} /* if (wrong buffer) ... */
/* now we have the right buffer loaded. Copy out the
* data from here to the user's buffer.
*/
bufIndex = offset.LowPart & (buf_bufferSize - 1);
/* and figure out how many bytes we want from this buffer */
nbytes = buf_bufferSize - bufIndex; /* what remains in buffer */
if (nbytes > count)
nbytes = count; /* don't go past end of request */
/* now copy the data */
#ifdef DJGPP
if (dosflag)
dosmemget((dos_ptr)op, nbytes, bufferp->datap + bufIndex);
else
#endif /* DJGPP */
memcpy(bufferp->datap + bufIndex, op, nbytes);
buf_SetDirty(bufferp);
/* and record the last writer */
if (bufferp->userp != userp) {
cm_HoldUser(userp);
if (bufferp->userp)
cm_ReleaseUser(bufferp->userp);
bufferp->userp = userp;
}
/* adjust counters, pointers, etc. */
op += nbytes;
count -= nbytes;
written += nbytes;
thyper.LowPart = nbytes;
thyper.HighPart = 0;
offset = LargeIntegerAdd(thyper, offset);
} /* while 1 */
done:
lock_ReleaseMutex(&scp->mx);
if (bufferp) {
lock_ReleaseMutex(&bufferp->mx);
buf_Release(bufferp);
}
if (code == 0 /* && filter != 0 && (fidp->flags & SMB_FID_NTOPEN)
&& (fidp->NTopen_dscp->flags & CM_SCACHEFLAG_ANYWATCH)*/) {
/*smb_NotifyChange(FILE_ACTION_MODIFIED, filter,
fidp->NTopen_dscp, fidp->NTopen_pathp,
NULL, TRUE);*/
}
if (code == 0 && doWriteBack) {
lock_ObtainMutex(&scp->mx);
cm_SyncOp(scp, NULL, userp, &req, 0, CM_SCACHESYNC_ASYNCSTORE);
lock_ReleaseMutex(&scp->mx);
cm_QueueBKGRequest(scp, cm_BkgStore, writeBackOffset.LowPart,
writeBackOffset.HighPart, cm_chunkSize, 0, userp);
}
return code;
}

2496
src/WINNT/afsrdr/afsrdr.c Normal file

File diff suppressed because it is too large Load Diff

68
src/WINNT/afsrdr/afsrdr.h Normal file
View File

@ -0,0 +1,68 @@
/* copyright (c) 2005
* the regents of the university of michigan
* all rights reserved
*
* permission is granted to use, copy, create derivative works and
* redistribute this software and such derivative works for any purpose,
* so long as the name of the university of michigan is not used in
* any advertising or publicity pertaining to the use or distribution
* of this software without specific, written prior authorization. if
* the above copyright notice or any other identification of the
* university of michigan is included in any copy of any portion of
* this software, then the disclaimer below must also be included.
*
* this software is provided as is, without representation from the
* university of michigan as to its fitness for any purpose, and without
* warranty by the university of michigan of any kind, either express
* or implied, including without limitation the implied warranties of
* merchantability and fitness for a particular purpose. the regents
* of the university of michigan shall not be liable for any damages,
* including special, indirect, incidental, or consequential damages,
* with respect to any claim arising out or in connection with the use
* of the software, even if it has been or is hereafter advised of the
* possibility of such damages.
*/
/* versioning history
*
* 03-jun 2005 (eric williams) entered into versioning
*/
#include <ntifs.h>
#define rpt0(args)
#define rpt1(args)
#define rpt2(args)
#define rpt3(args)
#define rpt4(args)
#define rpt5(args)
struct AfsRdrExtension
{
struct ComExtension *com;
KMUTEX protectMutex;
PNOTIFY_SYNC notifyList;
LIST_ENTRY listHead;
NPAGED_LOOKASIDE_LIST fcbMemList;
FAST_MUTEX fcbLock;
NPAGED_LOOKASIDE_LIST ccbMemList;
RTL_GENERIC_TABLE fcbTable;
CACHE_MANAGER_CALLBACKS callbacks;
};
struct ComExtension
{
struct AfsRdrExtension *rdr;
LIST_ENTRY outReqList;
KSPIN_LOCK outLock;
RTL_GENERIC_TABLE inTable;
FAST_MUTEX inLock;
KEVENT outEvent, cancelEvent;
};
extern struct AfsRdrExtension *rdrExt;
extern struct ComExtension *comExt;
void ifs_lock_rpcs();
void ifs_unlock_rpcs();

1407
src/WINNT/afsrdr/ifs_rpc.c Normal file

File diff suppressed because it is too large Load Diff

113
src/WINNT/afsrdr/ifs_rpc.h Normal file
View File

@ -0,0 +1,113 @@
/* copyright (c) 2005
* the regents of the university of michigan
* all rights reserved
*
* permission is granted to use, copy, create derivative works and
* redistribute this software and such derivative works for any purpose,
* so long as the name of the university of michigan is not used in
* any advertising or publicity pertaining to the use or distribution
* of this software without specific, written prior authorization. if
* the above copyright notice or any other identification of the
* university of michigan is included in any copy of any portion of
* this software, then the disclaimer below must also be included.
*
* this software is provided as is, without representation from the
* university of michigan as to its fitness for any purpose, and without
* warranty by the university of michigan of any kind, either express
* or implied, including without limitation the implied warranties of
* merchantability and fitness for a particular purpose. the regents
* of the university of michigan shall not be liable for any damages,
* including special, indirect, incidental, or consequential damages,
* with respect to any claim arising out or in connection with the use
* of the software, even if it has been or is hereafter advised of the
* possibility of such damages.
*/
/* versioning history
*
* 03-jun 2005 (eric williams) entered into versioning
*/
#ifdef RPC_KERN
#include <ntifs.h>
#include <stdlib.h>
#else
#include <osi.h>
#include <windows.h>
#include <winioctl.h>
#endif
/* upcalls */
#define RPC_NAMEI 0x10
#define RPC_CHECK_ACCESS 0x11
#define RPC_CREATE 0x12
#define RPC_STAT 0x13
#define RPC_READ 0x14
#define RPC_WRITE 0x15
#define RPC_TRUNC 0x16
#define RPC_SETINFO 0x17
#define RPC_READDIR 0x18
#define RPC_CLOSE 0x19
#define RPC_UNLINK 0x1A
#define RPC_IOCTL_WRITE 0x1B
#define RPC_IOCTL_READ 0x1C
#define RPC_RENAME 0x1D
#define RPC_READ_BULK 0x1E
#define RPC_WRITE_BULK 0x1F
/* downcalls */
#define RPC_BREAK_CALLBACK 0x80
#define TRANSFER_CHUNK_SIZE (1024*1024)
#define RPC_TIMEOUT_SHORT 0
#define RPC_TIMEOUT_LONG 1
/* internal data struct for both client and server */
struct rpc
{
#ifdef RPC_KERN
struct rpc *next;
int size;
KEVENT ev;
MDL *bulk_mdl;
#endif
char *bulk_out;
ULONG *bulk_out_len;
char *bulk_in;
ULONG bulk_in_len, bulk_in_max;
ULONG key;
char *out_buf, *out_pos;
char *in_buf, *in_pos;
int status;
};
typedef struct rpc rpc_t;
/* application interface into rpc library */
#ifdef RPC_KERN
rpc_call(ULONG in_len, char *in_buf, ULONG out_max, char *out_buf, ULONG *out_len);
rpc_set_context(void *context);
rpc_remove_context();
rpc_get_len(rpc_t *rpc);
rpc_send(char *out_buf, int out_len, int *out_written);
rpc_recv(char *in_buf, ULONG len);
rpc_shutdown();
#else
rpc_parse(rpc_t *rpc);
#endif
/* extended information */
struct readdir_data
{
LARGE_INTEGER cookie;
long offset;
LARGE_INTEGER creation, access, write, change, size;
ULONG attribs, name_length; /* chars */
CCHAR short_name_length; /* chars */
WCHAR short_name[14];
WCHAR name[];
};
typedef struct readdir_data readdir_data_t;

90
src/WINNT/afsrdr/kif.h Normal file
View File

@ -0,0 +1,90 @@
/* copyright (c) 2005
* the regents of the university of michigan
* all rights reserved
*
* permission is granted to use, copy, create derivative works and
* redistribute this software and such derivative works for any purpose,
* so long as the name of the university of michigan is not used in
* any advertising or publicity pertaining to the use or distribution
* of this software without specific, written prior authorization. if
* the above copyright notice or any other identification of the
* university of michigan is included in any copy of any portion of
* this software, then the disclaimer below must also be included.
*
* this software is provided as is, without representation from the
* university of michigan as to its fitness for any purpose, and without
* warranty by the university of michigan of any kind, either express
* or implied, including without limitation the implied warranties of
* merchantability and fitness for a particular purpose. the regents
* of the university of michigan shall not be liable for any damages,
* including special, indirect, incidental, or consequential damages,
* with respect to any claim arising out or in connection with the use
* of the software, even if it has been or is hereafter advised of the
* possibility of such damages.
*/
/* versioning history
*
* 03-jun 2005 (eric williams) entered into versioning
*/
/* error codes */
#define IFSL_SUCCESS_BASE 0x00000000
#define IFSL_FAIL_BASE 0x80000000
#define IFSL_SUCCESS (IFSL_SUCCESS_BASE + 0)
#define IFSL_DOES_NOT_EXIST (IFSL_FAIL_BASE + 1)
#define IFSL_NOT_IMPLEMENTED (IFSL_FAIL_BASE + 2)
#define IFSL_END_OF_ENUM (IFSL_SUCCESS_BASE + 3)
#define IFSL_CANNOT_MAKE (IFSL_FAIL_BASE + 4)
#define IFSL_END_OF_FILE (IFSL_SUCCESS_BASE + 5)
#define IFSL_NO_ACCESS (IFSL_FAIL_BASE + 6)
#define IFSL_BUFFER_TOO_SMALL (IFSL_FAIL_BASE + 7)
#define IFSL_SHARING_VIOLATION (IFSL_FAIL_BASE + 8)
#define IFSL_BAD_INPUT (IFSL_FAIL_BASE + 9)
#define IFSL_GENERIC_FAILURE (IFSL_FAIL_BASE + 10)
#define IFSL_OPEN_CREATED (IFSL_SUCCESS_BASE + 11)
#define IFSL_OPEN_EXISTS (IFSL_FAIL_BASE + 12)
#define IFSL_OPEN_OPENED (IFSL_SUCCESS_BASE + 13)
#define IFSL_OPEN_OVERWRITTEN (IFSL_SUCCESS_BASE + 14)
#define IFSL_OPEN_SUPERSCEDED (IFSL_SUCCESS_BASE + 15)
#define IFSL_BADFILENAME (IFSL_FAIL_BASE + 16)
#define IFSL_READONLY (IFSL_FAIL_BASE + 17)
#define IFSL_IS_A_DIR (IFSL_FAIL_BASE + 18)
#define IFSL_PATH_DOES_NOT_EXIST (IFSL_FAIL_BASE + 19)
#define IFSL_IS_A_FILE (IFSL_FAIL_BASE + 20)
#define IFSL_NO_FILE (IFSL_FAIL_BASE + 21)
#define IFSL_NOT_EMPTY (IFSL_FAIL_BASE + 22)
#define IFSL_RPC_TIMEOUT (IFSL_FAIL_BASE + 23)
#define IFSL_OVERQUOTA (IFSL_FAIL_BASE + 24)
#define IFSL_UNSPEC (IFSL_FAIL_BASE + 25)
/* ioctl codes */
#define IOCTL_AFSRDR_IOCTL CTL_CODE(IOCTL_DISK_BASE, 0x007, METHOD_OUT_DIRECT, FILE_ANY_ACCESS)
#define IOCTL_AFSRDR_DOWNCALL CTL_CODE(IOCTL_DISK_BASE, 0x008, METHOD_OUT_DIRECT, FILE_ANY_ACCESS)
#define IOCTL_AFSRDR_GET_PATH CTL_CODE(IOCTL_DISK_BASE, 0x009, METHOD_OUT_DIRECT, FILE_ANY_ACCESS)
/* upcalls */
uc_namei(WCHAR *name, ULONG *fid);
uc_check_access(ULONG fid, ULONG access, ULONG *granted);
uc_create(WCHAR *str, ULONG attribs, LARGE_INTEGER alloc, ULONG access, ULONG *granted, ULONG *fid);
uc_stat(ULONG fid, ULONG *attribs, LARGE_INTEGER *size, LARGE_INTEGER *creation, LARGE_INTEGER *access, LARGE_INTEGER *change, LARGE_INTEGER *written);
uc_setinfo(ULONG fid, ULONG attribs, LARGE_INTEGER creation, LARGE_INTEGER access, LARGE_INTEGER change, LARGE_INTEGER written);
uc_trunc(ULONG fid, LARGE_INTEGER size);
uc_read(ULONG fid, LARGE_INTEGER offset, ULONG length, ULONG *read, char *data);
uc_write(ULONG fid, LARGE_INTEGER offset, ULONG length, ULONG *written, char *data);
/*#ifdef RPC_KERN
uc_read_mdl(ULONG fid, LARGE_INTEGER offset, ULONG length, ULONG *read, MDL *data);
uc_write_mdl(ULONG fid, LARGE_INTEGER offset, ULONG length, ULONG *written, MDL *mdl);
#endif*/
uc_readdir(ULONG fid, LARGE_INTEGER cookie_in, WCHAR *filter, ULONG *count, char *data, ULONG *len);
uc_close(ULONG fid);
uc_unlink(WCHAR *name);
uc_ioctl_write(ULONG length, char *data, ULONG *key);
uc_ioctl_read(ULONG key, ULONG *length, char *data);
uc_rename(ULONG fid, WCHAR *curr, WCHAR *new_dir, WCHAR *new_name, ULONG *new_fid);
/* downcalls */
dc_break_callback(ULONG fid);

View File

@ -0,0 +1 @@
!INCLUDE $(NTMAKEENV)\makefile.def

31
src/WINNT/afsrdr/sources Normal file
View File

@ -0,0 +1,31 @@
#/* copyright (c) 2005
# * the regents of the university of michigan
# * all rights reserved
# *
# * permission is granted to use, copy, create derivative works and
# * redistribute this software and such derivative works for any purpose,
# * so long as the name of the university of michigan is not used in
# * any advertising or publicity pertaining to the use or distribution
# * of this software without specific, written prior authorization. if
# * the above copyright notice or any other identification of the
# * university of michigan is included in any copy of any portion of
# * this software, then the disclaimer below must also be included.
# *
# * this software is provided as is, without representation from the
# * university of michigan as to its fitness for any purpose, and without
# * warranty by the university of michigan of any kind, either express
# * or implied, including without limitation the implied warranties of
# * merchantability and fitness for a particular purpose. the regents
# * of the university of michigan shall not be liable for any damages,
# * including special, indirect, incidental, or consequential damages,
# * with respect to any claim arising out or in connection with the use
# * of the software, even if it has been or is hereafter advised of the
# * possibility of such damages.
# */
SOURCES= afsrdr.c ifs_rpc.c
TARGETNAME=afsrdr
TARGETPATH=obj
TARGETTYPE=DRIVER
DRIVERTYPE=FS
C_DEFINES=-DUNICODE -DRPT_CLI -DRPC_KERN

View File

@ -6,6 +6,30 @@
* License. For details, see the LICENSE file in the top-level source
* directory or online at http://www.openafs.org/dl/license10.html
*/
/* copyright (c) 2005
* the regents of the university of michigan
* all rights reserved
*
* permission is granted to use, copy, create derivative works and
* redistribute this software and such derivative works for any purpose,
* so long as no fee is charged, and so long as the copyright notice
* above, this grant of permission, and the disclaimer below appear
* in all copies made; and so long as the name of the university of
* michigan is not used in any advertising or publicity pertaining
* to the use or distribution of this software without specific, written
* prior authorization.
*
* this software is provided as is, without representation from the
* university of michigan as to its fitness for any purpose, and without
* warranty by the university of michigan of any kind, either express
* or implied, including without limitation the implied warranties of
* merchantability and fitness for a particular purpose. the regents
* of the university of michigan shall not be liable for nay damages,
* including special, indirect, incidental, or consequential damages,
* with respect to ant claim arising out of or in connection with the
* use of the software, even if it has been or is hereafter advised
* of the possibility of such damages.
*/
extern "C" {
#include <afs/param.h>
@ -314,9 +338,16 @@ BOOL SubmountToPath (PDRIVEMAPLIST pList, LPTSTR pszPath, LPTSTR pszSubmount, BO
// Otherwise, look up our list of submounts.
//
#ifdef AFSIFS
AdjustAfsPath (pszPath, pszSubmount, TRUE, TRUE);
#endif
for (size_t ii = 0; ii < pList->cSubmounts; ++ii)
{
#ifndef AFSIFS
if (!lstrcmpi (pList->aSubmounts[ii].szSubmount, pszSubmount))
#else
if (!lstrcmpi (pList->aSubmounts[ii].szMapping, pszPath))
#endif
{
if (fMarkInUse)
pList->aSubmounts[ii].fInUse = TRUE;
@ -815,7 +846,11 @@ BOOL ActivateDriveMap (TCHAR chDrive, LPTSTR pszMapping, LPTSTR pszSubmountReq,
}
// We now have a submount name and drive letter--map the network drive.
#ifndef AFSIFS
DWORD rc=MountDOSDrive(chDrive,szSubmount,fPersistent,NULL);
#else
DWORD rc=MountDOSDrive(chDrive,/*szSubmount*/pszMapping,fPersistent,NULL);
#endif
if (rc == NO_ERROR)
return TRUE;
@ -931,10 +966,25 @@ BOOL GetDriveSubmount (TCHAR chDrive, LPTSTR pszSubmountNow)
// <AuthID>: Authentication ID, 16 char hex.
// <netbiosname>: Netbios name of server
//
#ifndef AFSIFS
if (_tcsnicmp(szMapping, cszLANMANDEVICE, _tcslen(cszLANMANDEVICE)))
#else
const TCHAR ker_sub_path[] = "\\Device\\afsrdr\\";
if (_tcsnicmp(szMapping, ker_sub_path, _tcslen(ker_sub_path)))
#endif
return FALSE;
#ifndef AFSIFS
pszSubmount = &szMapping[ _tcslen(cszLANMANDEVICE) ];
#else
pszSubmount = &szMapping[ _tcslen(ker_sub_path) ];
#endif
#ifdef AFSIFS
if (*(pszSubmount) < '0' ||
*(pszSubmount) > '9')
return FALSE;
++pszSubmount;
#else
if (IsWindows2000())
{
if (*(pszSubmount) != TEXT(';'))
@ -970,6 +1020,7 @@ BOOL GetDriveSubmount (TCHAR chDrive, LPTSTR pszSubmountNow)
return FALSE;
pszSubmount += _tcslen(szNetBiosName);
#endif
}
else // (!IsWindowsNT())
{
@ -991,7 +1042,12 @@ BOOL GetDriveSubmount (TCHAR chDrive, LPTSTR pszSubmountNow)
if (!pszSubmount || !*pszSubmount)
return FALSE;
#ifndef AFSIFS
lstrcpy (pszSubmountNow, pszSubmount);
#else
lstrcpy (pszSubmountNow, "\\afs");
lstrcat (pszSubmountNow, pszSubmount);
#endif
return TRUE;
}
@ -1358,9 +1414,43 @@ BOOL GlobalMountDrive()
DWORD MountDOSDrive(char chDrive,const char *szSubmount,BOOL bPersistent,const char * pUsername)
{
TCHAR szPath[MAX_PATH];
DWORD err;
BOOL succ;
TCHAR szPath[MAX_PATH], szTokens[MAX_PATH], *tok;
TCHAR szClient[MAX_PATH];
TCHAR szDrive[3] = TEXT("?:");
#ifdef AFSIFS
int pathCount, currPos, lastPos, x;
pathCount = 0;
pathCount = 0;
strcpy(szTokens, szSubmount);
tok = strtok(szTokens, "/\\");
strcpy(szPath, "");
while (tok)
{
if (pathCount || stricmp(tok, "afs"))
{
strcat(szPath, "\\");
strcat(szPath, tok);
pathCount++;
}
tok = strtok(NULL, "/\\");
}
sprintf(szDrive,"%c:",chDrive);
strcpy(szTokens, szPath);
sprintf(szPath,"\\Device\\afsrdr\\%d%s",pathCount,szTokens);
//succ = DefineDosDevice(DDD_RAW_TARGET_PATH, "J:", "\\Device\\afsrdr\\2\\ericjw\\test");
succ = DefineDosDevice(DDD_RAW_TARGET_PATH, szDrive, szPath);
err = GetLastError();
return succ ? NO_ERROR : ERROR_DEVICE_IN_USE;
#else
sprintf(szDrive,"%c:",chDrive);
GetClientNetbiosName (szClient);
sprintf(szPath,"\\\\%s\\%s",szClient,szSubmount);
@ -1375,11 +1465,19 @@ DWORD MountDOSDrive(char chDrive,const char *szSubmount,BOOL bPersistent,const c
(bPersistent)?"Persistant" : "NonPresistant",
szDrive,szPath,pUsername?pUsername:"NULL",res);
return res;
#endif
}
DWORD DisMountDOSDriveFull(const char *szPath,BOOL bForce)
{
#ifndef AFSIFS
DWORD res=WNetCancelConnection(szPath,bForce);
#else
DWORD res;
res = ERROR_DEVICE_IN_USE;
// must handle drive letters and afs paths
//DDD_REMOVE_DEFINITION
#endif
DEBUG_EVENT3("AFS DriveMap","%sDismount Remote[%s]=%x",
bForce ? "Forced " : "",szPath,res);
return (res==ERROR_NOT_CONNECTED)?NO_ERROR:res;
@ -1398,6 +1496,13 @@ DWORD DisMountDOSDrive(const char *pSubmount,BOOL bForce)
DWORD DisMountDOSDrive(const char chDrive,BOOL bForce)
{
TCHAR szPath[MAX_PATH];
sprintf(szPath,"%c:",chDrive);
DWORD succ;
sprintf(szPath,"%c:",chDrive);
#ifdef AFSIFS
succ = DefineDosDevice(DDD_REMOVE_DEFINITION, szPath, NULL);
return (!succ) ? GetLastError() : 0;
#else
return DisMountDOSDriveFull(szPath,bForce);
#endif
}

View File

@ -89,6 +89,9 @@ prebuild:
!else if ("$(AFSVER_CL)" == "1300")
echo !define CL_1300 1 >> $(OUT)\nsi-includes.nsi
!endif
!if ("$(AFSIFS)" == "TRUE")
echo !define AFSIFS 1 >> $(OUT)\nsi-includes.nsi
!endif
!if ("$(AFSDEV_BUILDTYPE)" == "CHECKED")
echo !define DEBUG 1 >>$(OUT)\nsi-includes.nsi
!endif

View File

@ -49,7 +49,7 @@ VIAddVersionKey "CompanyName" "OpenAFS.org"
VIAddVersionKey "ProductVersion" ${AFS_VERSION}
VIAddVersionKey "FileVersion" ${AFS_VERSION}
VIAddVersionKey "FileDescription" "OpenAFS for Windows Installer"
VIAddVersionKey "LegalCopyright" "(C)2000-2004"
VIAddVersionKey "LegalCopyright" "(C)2000-2005"
!ifdef DEBUG
VIAddVersionKey "PrivateBuild" "Checked/Debug"
!endif ; End DEBUG
@ -64,10 +64,18 @@ VIAddVersionKey "PrivateBuild" "Checked/Debug"
!define REPLACEDLL_NOREGISTER
;General
!ifndef AFSIFS
!ifndef DEBUG
OutFile "${AFS_DESTDIR}\WinInstall\OpenAFSforWindows.exe"
!else
OutFile "${AFS_DESTDIR}\WinInstall\OpenAFSforWindows-DEBUG.exe"
!endif
!else
!ifndef DEBUG
OutFile "${AFS_DESTDIR}\WinInstall\OpenAFSforWindows-IFS.exe"
!else
OutFile "${AFS_DESTDIR}\WinInstall\OpenAFSforWindows-IFS-DEBUG.exe"
!endif
!endif
SilentInstall normal
SetCompressor lzma
@ -483,6 +491,7 @@ var REG_VALUE
var REG_DATA_1
var REG_DATA_2
var REG_DATA_3
var REG_DATA_4
;--------------------------------
@ -547,6 +556,13 @@ Section "AFS Client" secClient
SetOutPath "$SYSDIR"
!insertmacro ReplaceDLL "${AFS_CLIENT_BUILDDIR}\afslogon.dll" "$SYSDIR\afslogon.dll" "$INSTDIR"
File "${AFS_CLIENT_BUILDDIR}\afscpcc.exe"
!ifdef AFSIFS
!ifndef DEBUG
!insertmacro ReplaceDLL "..\..\afsrdr\objfre_w2K_x86\i386\afsrdr.sys" "$SYSDIR\DRIVERS\afsrdr.sys" "$INSTDIR"
!else
!insertmacro ReplaceDLL "..\..\afsrdr\objchk_w2K_x86\i386\afsrdr.sys" "$SYSDIR\DRIVERS\afsrdr.sys" "$INSTDIR"
!endif
!endif
Call AFSLangFiles
@ -660,6 +676,7 @@ Section "AFS Client" secClient
SetOutPath "$INSTDIR\Common"
File "${AFS_WININSTALL_DIR}\Service.exe"
nsExec::Exec "net stop TransarcAFSDaemon"
nsExec::Exec "net stop AfsRdr"
;IMPORTANT! If we are not refreshing the config files, do NOT remove the service
;Don't re-install because it must be present or we wouldn't have passed the Reg check
@ -667,6 +684,10 @@ Section "AFS Client" secClient
StrCmp $R2 "" +1 skipremove
nsExec::Exec '$INSTDIR\Common\Service.exe u TransarcAFSDaemon'
nsExec::Exec '$INSTDIR\Common\Service.exe TransarcAFSDaemon "$INSTDIR\Client\Program\afsd_service.exe" "OpenAFS Client Service"'
nsExec::Exec '$INSTDIR\Common\Service.exe u AfsRdr'
!ifdef AFSIFS
nsExec::Exec '$INSTDIR\Common\Service.exe AfsRdr "$SYSDIR\DRIVERS\afsrdr.sys" "AFS Redirector"'
!endif
skipremove:
Delete "$INSTDIR\Common\service.exe"
@ -711,13 +732,28 @@ skipremove:
strcpy $REG_DATA_1 "PNP_TDI"
strcpy $REG_DATA_2 ""
strcpy $REG_DATA_3 ""
strcpy $REG_DATA_4 ""
Call RegWriteMultiStr
strcpy $REG_SUB_KEY "SYSTEM\CurrentControlSet\Services\TransarcAFSDaemon"
strcpy $REG_VALUE "DependOnService"
strcpy $REG_DATA_1 "Tcpip"
strcpy $REG_DATA_2 "NETBIOS"
strcpy $REG_DATA_3 "RpcSs"
!ifdef AFSIFS
strcpy $REG_DATA_4 "AfsRdr"
!else
strcpy $REG_DATA_4 ""
!endif
Call RegWriteMultiStr
!ifdef AFSIFS
strcpy $REG_SUB_KEY "SYSTEM\CurrentControlSet\Services\AfsRdr"
strcpy $REG_VALUE "DependOnService"
strcpy $REG_DATA_1 "Tcpip"
strcpy $REG_DATA_2 ""
strcpy $REG_DATA_3 ""
strcpy $REG_DATA_4 ""
Call RegWriteMultiStr
!endif
; WinLogon Event Notification
WriteRegDWORD HKLM "Software\Microsoft\Windows NT\CurrentVersion\WinLogon\Notify\AfsLogon" "Asynchronous" 0
@ -3774,6 +3810,12 @@ Function RegWriteMultiStr
System::Call "*$2(&t$9 '$REG_DATA_3')" ; Place the string
IntOp $2 $2 + $9 ; Advance to the next position
StrCmp '$REG_DATA_4' "" terminate
StrLen $9 '$REG_DATA_4' ; Length of third string
IntOp $9 $9 + 1 ; Plus null
System::Call "*$2(&t$9 '$REG_DATA_4')" ; Place the string
IntOp $2 $2 + $9 ; Advance to the next position
terminate:
System::Call "*$2(&t1 '')" ; Place the terminating null
IntOp $2 $2 + 1 ; Advance to the next position

View File

@ -13,6 +13,8 @@
int main(int argc, char *argv[])
{
DWORD type, start;
if(argc<3)
{
printf("Insufficient arguments: Service ServiceName ServicePath DisplayName.\n");
@ -31,11 +33,21 @@ int main(int argc, char *argv[])
if(*argv[1]!='u' && *argv[1]!='U')
{
if (!stricmp(argv[2] + strlen(argv[2]) - 3, "sys"))
{
type = SERVICE_FILE_SYSTEM_DRIVER;
start = SERVICE_DEMAND_START;
}
else
{
type = SERVICE_WIN32_OWN_PROCESS;
start = SERVICE_AUTO_START;
}
hService = CreateService(hSCM, argv[1],
_T(argv[3]),
SERVICE_ALL_ACCESS,
SERVICE_WIN32_OWN_PROCESS,
SERVICE_AUTO_START,
type,
start,
SERVICE_ERROR_IGNORE,
argv[2],
NULL,NULL,NULL, NULL, NULL );

View File

@ -256,6 +256,12 @@ afscdefs = $(afscdefs) /G7
!ENDIF
!ENDIF
!IF ("$(AFSIFS)" == "TRUE")
dafsifs = "-DAFSIFS"
!ELSE
dafsifs = ""
!ENDIF
!IF ("$(AFSDEV_BUILDTYPE)" == "FREE")
afscflags = $(afscflags) /Ox /Zi
@ -296,7 +302,7 @@ AFSDEV_WARNLEVEL = 3
afscflags = $(afscflags) /W$(AFSDEV_WARNLEVEL)
# C/C++ compilation macros
C2OBJ = $(cc) /Fo$@ /Fd$*.pdb $(cflags) $(cdebug) $(cvarsdll) $(afscflags) $(afscdefs) /c
C2OBJ = $(cc) /Fo$@ /Fd$*.pdb $(cflags) $(cdebug) $(dafsifs) $(cvarsdll) $(afscflags) $(afscdefs) /c
CPP2OBJ = $(C2OBJ)
# Inference rules for building and installing targets
# Compile .c files, from current directory to defined by OUT

View File

@ -83,13 +83,25 @@ goto usage
:checked
set AFSBLD_TYPE=CHECKED
set AFSDEV_CRTDEBUG=1
goto args_done
goto ifs_arg
:free
set AFSBLD_TYPE=FREE
set AFSDEV_CRTDEBUG=0
goto ifs_arg
:ifs_arg
set AFSIFS=
if "%2"=="ifs" goto is_ifs
if "%2"=="IFS" goto is_ifs
goto args_done
:is_ifs
set AFSIFS=TRUE
:args_done
REM #######################################################################

View File

@ -6,6 +6,30 @@
* License. For details, see the LICENSE file in the top-level source
* directory or online at http://www.openafs.org/dl/license10.html
*/
/* copyright (c) 2005
* the regents of the university of michigan
* all rights reserved
*
* permission is granted to use, copy, create derivative works and
* redistribute this software and such derivative works for any purpose,
* so long as the name of the university of michigan is not used in
* any advertising or publicity pertaining to the use or distribution
* of this software without specific, written prior authorization. if
* the above copyright notice or any other identification of the
* university of michigan is included in any copy of any portion of
* this software, then the disclaimer below must also be included.
*
* this software is provided as is, without representation from the
* university of michigan as to its fitness for any purpose, and without
* warranty by the university of michigan of any kind, either express
* or implied, including without limitation the implied warranties of
* merchantability and fitness for a particular purpose. the regents
* of the university of michigan shall not be liable for any damages,
* including special, indirect, incidental, or consequential damages,
* with respect to any claim arising out or in connection with the use
* of the software, even if it has been or is hereafter advised of the
* possibility of such damages.
*/
#include <afsconfig.h>
#include <afs/param.h>
@ -42,6 +66,7 @@ RCSID
#include <pioctl_nt.h>
#include <WINNT/afsreg.h>
#include <lanahelper.h>
#include <WINNT/afsrdr/kif.h>
#include <loadfuncs-krb5.h>
#include <krb5.h>
@ -315,6 +340,7 @@ GetIoctlHandle(char *fileNamep, HANDLE * handlep)
DWORD gle;
DWORD dwSize = sizeof(szUser);
#ifndef AFSIFS
if (fileNamep) {
drivep = strchr(fileNamep, ':');
if (drivep && (drivep - fileNamep) >= 1) {
@ -365,14 +391,25 @@ GetIoctlHandle(char *fileNamep, HANDLE * handlep)
lana_GetNetbiosName(netbiosName,LANA_NETBIOS_NAME_FULL);
sprintf(tbuffer,"\\\\%s\\all%s",netbiosName,SMB_IOCTL_FILENAME);
}
#else
sprintf(tbuffer,"\\\\.\\afscom\\ioctl");
#endif
fflush(stdout);
/* now open the file */
fh = CreateFile(tbuffer, GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
FILE_FLAG_WRITE_THROUGH, NULL);
fflush(stdout);
if (fh == INVALID_HANDLE_VALUE) {
fflush(stdout);
#ifdef AFSIFS
if (fh == INVALID_HANDLE_VALUE) {
return -1;
}
#endif
if (fh == INVALID_HANDLE_VALUE) {
int gonext = 0;
gle = GetLastError();
@ -593,6 +630,7 @@ Transceive(HANDLE handle, fs_ioctlRequest_t * reqp)
long rcount;
long ioCount;
DWORD gle;
char *data;
rcount = reqp->mp - reqp->data;
if (rcount <= 0) {
@ -601,7 +639,8 @@ Transceive(HANDLE handle, fs_ioctlRequest_t * reqp)
return EINVAL; /* not supposed to happen */
}
if (!WriteFile(handle, reqp->data, rcount, &ioCount, NULL)) {
#ifndef AFSIFS
if (!WriteFile(handle, reqp->data, rcount, &ioCount, NULL)) {
/* failed to write */
gle = GetLastError();
@ -618,6 +657,17 @@ Transceive(HANDLE handle, fs_ioctlRequest_t * reqp)
fprintf(stderr, "pioctl Transceive ReadFile failed: 0x%X\r\n",gle);
return gle;
}
#else
/* ioctl completes as one operation, so copy input to a new buffer, and use as output buffer */
data = malloc(rcount);
memcpy(data, reqp->data, rcount);
if (!DeviceIoControl(handle, IOCTL_AFSRDR_IOCTL, data, rcount, reqp->data, sizeof(reqp->data), &ioCount, NULL))
{
free(data);
return GetLastError();
}
free(data);
#endif
reqp->nbytes = ioCount; /* set # of bytes available */
reqp->mp = reqp->data; /* restart marshalling */
@ -691,6 +741,34 @@ fs_GetFullPath(char *pathp, char *outPathp, long outSize)
int pathHasDrive;
int doSwitch;
char newPath[3];
HANDLE rootDir;
wchar_t *wpath;
unsigned long length;
#ifdef AFSIFS
if (!pathp)
return CM_ERROR_NOSUCHPATH;
//sprintf(tpath, "%c:\\", pathp[0]);
rootDir = CreateFile(pathp, 0, 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
if (rootDir == INVALID_HANDLE_VALUE)
return CM_ERROR_NOSUCHPATH;
wpath = tpath;
length = 0;
if (!DeviceIoControl(rootDir, IOCTL_AFSRDR_GET_PATH, NULL, 0, wpath, 1000, &length, NULL))
{
CloseHandle(rootDir);
return CM_ERROR_NOSUCHPATH;
}
CloseHandle(rootDir);
code = WideCharToMultiByte(CP_UTF8, 0/*WC_NO_BEST_FIT_CHARS*/, wpath, length/sizeof(wchar_t), outPathp, outSize/sizeof(wchar_t), NULL, NULL);
// strcpy(outPathp, tpath);
return 0;
#endif
if (pathp[0] != 0 && pathp[1] == ':') {
/* there's a drive letter there */
@ -746,6 +824,7 @@ fs_GetFullPath(char *pathp, char *outPathp, long outSize)
/* now get the absolute path to the current wdir in this drive */
GetCurrentDirectory(sizeof(tpath), tpath);
if (tpath[1] == ':')
#ifndef AFSIFS
strcpy(outPathp, tpath + 2); /* skip drive letter */
else if ( tpath[0] == '\\' && tpath[1] == '\\') {
/* UNC path - strip off the server and sharename */
@ -760,6 +839,26 @@ fs_GetFullPath(char *pathp, char *outPathp, long outSize)
} else {
strcpy(outPathp,&tpath[--i]);
}
#else
{
HANDLE rootDir;
strcpy(outPathp, tpath);
sprintf(outPathp, "%c:\\", tpath[0]);
rootDir = CreateFile(outPathp, 0, 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
if (!DeviceIoControl(rootDir, IOCTL_AFSRDR_GET_PATH, NULL, 0, absRoot_w, 100*sizeof(wchar_t), &length, NULL))
{
CloseHandle(rootDir);
return CM_ERROR_NOSUCHPATH;
}
CloseHandle(rootDir);
ifs_ConvertFileName(absRoot_w, length/sizeof(wchar_t), absRoot, 100);
}
#endif
} else {
/* this should never happen */
strcpy(outPathp, tpath);