From 380f9a46a3feda44621cfe94d93a9c70d3e9ff7f Mon Sep 17 00:00:00 2001 From: Jeffrey Altman Date: Thu, 3 Jun 2010 12:04:15 -0400 Subject: [PATCH] Windows: Update fs newcell and add VIOCNEWCELL2 The Windows version of "fs newcell" did not accept any parameters and behaved quite differently from the Unix version. Instead of permitting new cell information to be added, the Windows version simply forced the existing cell information to be reacquired. This update adds a new pioctl, VIOCNEWCELL2, to support the implementation of a Unix-style "fs newcell". The functionality added here differs from the Unix version in the following ways: 1. "fs newcell" with no arguments is still accepted in order to maintain compatibility with prior Windows behavior. 2. "fs newcell -cell -dns" instructs the cache manager to add the new cell but obtain the vldb server info from DNS. 3. "fs newcell -cell ... -registry" instructs the cache manager to add the new cell and also save the cell configuration data in the registry for use the next time the service restarts. 4. The -vlport and -fsport options are accepted although the -fsport value is currently unsupported by the cache manager. LICENSE MIT Change-Id: If62cc8e1c6cc8ba2defb4cd72dae8a87b4d915e0 Reviewed-on: http://gerrit.openafs.org/2080 Reviewed-by: Jeffrey Altman Reviewed-by: Derrick Brashear Tested-by: Jeffrey Altman --- src/WINNT/afsd/NTMakefile | 33 +++---- src/WINNT/afsd/cm_cell.c | 63 +++++++++++++ src/WINNT/afsd/cm_cell.h | 5 ++ src/WINNT/afsd/cm_config.c | 109 +++++++++++++++++++++- src/WINNT/afsd/cm_config.h | 7 ++ src/WINNT/afsd/cm_ioctl.c | 85 ++++++++++++++++++ src/WINNT/afsd/cm_ioctl.h | 2 + src/WINNT/afsd/fs.c | 214 +++++++++++++++++++++++++++++--------------- src/WINNT/afsd/smb_iocons.h | 5 ++ src/WINNT/afsd/smb_ioctl.c | 9 ++ src/WINNT/afsd/smb_ioctl.h | 2 + 11 files changed, 445 insertions(+), 89 deletions(-) diff --git a/src/WINNT/afsd/NTMakefile b/src/WINNT/afsd/NTMakefile index 8e92bb2..ba429a6 100644 --- a/src/WINNT/afsd/NTMakefile +++ b/src/WINNT/afsd/NTMakefile @@ -204,6 +204,23 @@ MIDL_FLAGS=/app_config \ .idl.h: midl $(MIDL_FLAGS) $(AFSDEV_AUXMIDLFLAGS) $< + +AFSD_SDKLIBS =\ + netapi32.lib \ + dnsapi.lib \ + mpr.lib \ + rpcrt4.lib \ + user32.lib \ + Dbghelp.lib \ + strsafe.lib \ + mpr.lib \ + secur32.lib \ + ole32.lib \ + oleaut32.lib \ + iphlpapi.lib \ + shell32.lib \ + shlwapi.lib + ############################################################################ # libafsconf.dll @@ -214,7 +231,7 @@ CONF_DLLLIBS = \ $(DESTDIR)\lib\afs\afsreg.lib $(CONF_DLLFILE): $(CONFOBJS) $(OUT)\libafsconf.res $(CONF_DLLLIBS) - $(DLLGUILINK) -def:libafsconf.def dnsapi.lib mpr.lib shell32.lib Rpcrt4.lib + $(DLLGUILINK) -def:libafsconf.def $(AFSD_SDKLIBS) $(_VC_MANIFEST_EMBED_DLL) $(DLLPREP) $(CODESIGN_USERLAND) @@ -400,20 +417,6 @@ $(EXEDIR)\afscpcc.exe: $(OUT)\afscpcc.obj $(OUT)\afscpcc.res $(LOGON_DLLLIBS) # afsd.exe AFSD_EXEFILE = $(EXEDIR)\afsd.exe -AFSD_SDKLIBS =\ - netapi32.lib \ - dnsapi.lib \ - mpr.lib \ - rpcrt4.lib \ - user32.lib \ - Dbghelp.lib \ - strsafe.lib \ - mpr.lib \ - secur32.lib \ - ole32.lib \ - oleaut32.lib \ - iphlpapi.lib shell32.lib shlwapi.lib - AFSD_EXELIBS =\ $(DESTDIR)\lib\libosi.lib \ $(DESTDIR)\lib\afs\mtafsvldb.lib \ diff --git a/src/WINNT/afsd/cm_cell.c b/src/WINNT/afsd/cm_cell.c index 317cd73..3e7e516 100644 --- a/src/WINNT/afsd/cm_cell.c +++ b/src/WINNT/afsd/cm_cell.c @@ -701,3 +701,66 @@ void cm_RemoveCellFromIDHashTable(cm_cell_t *cellp) } } +long +cm_CreateCellWithInfo( char * cellname, + char * linked_cellname, + unsigned short vlport, + afs_uint32 host_count, + char *hostname[], + afs_uint32 flags) +{ + afs_uint32 code = 0; + cm_cell_rock_t rock; + struct hostent *thp; + struct sockaddr_in vlSockAddr; + afs_uint32 i, j; + + rock.cellp = cm_GetCell(cellname, CM_FLAG_CREATE | CM_FLAG_NOPROBE); + rock.flags = 0; + + cm_FreeServerList(&rock.cellp->vlServersp, CM_FREESERVERLIST_DELETE); + + if (!(flags & CM_CELLFLAG_DNS)) { + for (i = 0; i < host_count; i++) { + thp = gethostbyname(hostname[i]); + if (thp) { + int foundAddr = 0; + for (j=0 ; thp->h_addr_list[j]; j++) { + if (thp->h_addrtype != AF_INET) + continue; + memcpy(&vlSockAddr.sin_addr.s_addr, + thp->h_addr_list[j], + sizeof(long)); + vlSockAddr.sin_port = htons(vlport ? vlport : 7003); + vlSockAddr.sin_family = AF_INET; + cm_AddCellProc(&rock, &vlSockAddr, hostname[i], CM_FLAG_NOPROBE); + } + } + } + lock_ObtainMutex(&rock.cellp->mx); + rock.cellp->flags &= ~CM_CELLFLAG_DNS; + } else if (cm_dnsEnabled) { + int ttl; + + code = cm_SearchCellByDNS(rock.cellp->name, NULL, &ttl, cm_AddCellProc, &rock); + lock_ObtainMutex(&rock.cellp->mx); + if (code == 0) { /* got cell from DNS */ + rock.cellp->flags |= CM_CELLFLAG_DNS; + rock.cellp->timeout = time(0) + ttl; +#ifdef DEBUG + fprintf(stderr, "cell %s: ttl=%d\n", rock.cellp->name, ttl); +#endif + } + } else { + lock_ObtainMutex(&rock.cellp->mx); + rock.cellp->flags &= ~CM_CELLFLAG_DNS; + } + rock.cellp->flags |= CM_CELLFLAG_VLSERVER_INVALID; + StringCbCopy(rock.cellp->linkedName, CELL_MAXNAMELEN, linked_cellname); + lock_ReleaseMutex(&rock.cellp->mx); + + if (rock.cellp->vlServersp) + cm_RandomizeServer(&rock.cellp->vlServersp); + + return code; +} diff --git a/src/WINNT/afsd/cm_cell.h b/src/WINNT/afsd/cm_cell.h index 10eed9e..a3d8931 100644 --- a/src/WINNT/afsd/cm_cell.h +++ b/src/WINNT/afsd/cm_cell.h @@ -81,4 +81,9 @@ extern long cm_AddCellProc(void *rockp, struct sockaddr_in *addrp, char *namep, extern cm_cell_t *cm_UpdateCell(cm_cell_t * cp, afs_uint32 flags); +extern long cm_CreateCellWithInfo( char * cellname, + char * linked_cellname, + unsigned short vlport, afs_uint32 host_count, + char *hostname[], afs_uint32 flags); + #endif /* __CELL_H_ENV_ */ diff --git a/src/WINNT/afsd/cm_config.c b/src/WINNT/afsd/cm_config.c index de17596..e335182 100644 --- a/src/WINNT/afsd/cm_config.c +++ b/src/WINNT/afsd/cm_config.c @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -722,7 +723,113 @@ long cm_SearchCellRegistry(afs_uint32 client, return ((dwForceDNS || dwServers == 0) ? CM_ERROR_FORCE_DNS_LOOKUP : 0); } -long cm_EnumerateCellRegistry(afs_uint32 client, cm_enumCellRegistryProc_t *procp, void *rockp) +/* + * Following the registry schema listed above, cm_AddCellToRegistry + * will either create or update the registry configuration data for + * the specified cellname. + */ +long cm_AddCellToRegistry( char * cellname, + char * linked_cellname, + unsigned short vlport, + afs_uint32 host_count, + char *hostname[], + afs_uint32 flags) +{ + HKEY hkCellServDB = 0, hkCellName = 0, hkServerName = 0; + DWORD dwPort, dwDisposition; + long code; + unsigned int i; + + if (RegCreateKeyEx( HKEY_LOCAL_MACHINE, + AFSREG_CLT_OPENAFS_SUBKEY "\\CellServDB", + 0, + NULL, + REG_OPTION_NON_VOLATILE, + KEY_READ|KEY_WRITE|KEY_QUERY_VALUE, + NULL, + &hkCellServDB, + &dwDisposition) != ERROR_SUCCESS) { + code = CM_ERROR_NOACCESS; + goto done; + } + + /* Perform a recursive deletion of the cellname key */ + SHDeleteKey( hkCellServDB, cellname); + + if (RegCreateKeyEx( hkCellServDB, + cellname, + 0, + NULL, + REG_OPTION_NON_VOLATILE, + KEY_READ|KEY_WRITE|KEY_QUERY_VALUE, + NULL, + &hkCellName, + &dwDisposition) != ERROR_SUCCESS || + (dwDisposition == REG_OPENED_EXISTING_KEY) ) { + code = CM_ERROR_NOACCESS; + goto done; + } + + /* If we get here, hkCellName is a handle to an empty key */ + + if (linked_cellname && linked_cellname[0]) { + code = RegSetValueEx( hkCellName, "LinkedCell", + 0, REG_SZ, + (BYTE *) linked_cellname, CELL_MAXNAMELEN); + } + + if (flags & CM_CELLFLAG_DNS) { + DWORD dwForceDNS = 1; + code = RegSetValueEx( hkCellName, "ForceDNS", + 0, REG_DWORD, + (BYTE *) &dwForceDNS, sizeof(DWORD)); + } + + for ( i = 0; i < host_count; i++ ) { + if (RegCreateKeyEx( hkCellName, + hostname[i], + 0, + NULL, + REG_OPTION_NON_VOLATILE, + KEY_READ|KEY_WRITE|KEY_QUERY_VALUE, + NULL, + &hkServerName, + &dwDisposition) != ERROR_SUCCESS || + (dwDisposition == REG_OPENED_EXISTING_KEY)) { + code = CM_ERROR_NOACCESS; + goto done; + } + + /* We have a handle to a valid server key. Now we need + * to add the server to the cell */ + + /* First, see if there is an alternate hostname specified */ + code = RegSetValueEx( hkServerName, "HostName", + 0, REG_SZ, + (BYTE *) hostname[i], (DWORD)strlen(hostname[i]) + 1); + + if (vlport) { + dwPort = vlport; + code = RegSetValueEx( hkServerName, "vlserver", + 0, REG_DWORD, + (BYTE *) &dwPort, (DWORD)sizeof(DWORD)); + } + RegCloseKey( hkServerName); + hkServerName = 0; + } + + done: + if (hkServerName) + RegCloseKey(hkServerName); + if (hkCellName) + RegCloseKey(hkCellName); + if (hkCellServDB) + RegCloseKey(hkCellServDB); + + return code; +} + +long cm_EnumerateCellRegistry(afs_uint32 client, cm_enumCellProc_t *procp, void *rockp) { HKEY hkCellServDB = 0; DWORD dwSize; diff --git a/src/WINNT/afsd/cm_config.h b/src/WINNT/afsd/cm_config.h index 2882907..85b2a0b 100644 --- a/src/WINNT/afsd/cm_config.h +++ b/src/WINNT/afsd/cm_config.h @@ -69,6 +69,13 @@ extern long cm_AppendNewCellLine(cm_configFile_t *filep, char *linep); extern long cm_CloseCellFile(cm_configFile_t *filep); +extern long cm_AddCellToRegistry( char * cellname, + char * linked_cellname, + unsigned short vlport, + afs_uint32 host_count, + char *hostname[], + afs_uint32 flags); + extern long cm_GetCellServDB(char *cellNamep, afs_uint32 len); extern void cm_GetConfigDir(char *dir, afs_uint32 len); diff --git a/src/WINNT/afsd/cm_ioctl.c b/src/WINNT/afsd/cm_ioctl.c index f7ffda8..d321ea3 100644 --- a/src/WINNT/afsd/cm_ioctl.c +++ b/src/WINNT/afsd/cm_ioctl.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include @@ -1530,6 +1531,90 @@ cm_IoctlNewCell(struct cm_ioctl *ioctlp, struct cm_user *userp) } /* + * VIOCNEWCELL2 internals. + * + * Assumes that pioctl path has been parsed or skipped. + * + * The pioctl data buffer consists of the following structure: + * + * afs_uint32 flags + * afs_uint32 alternative fs port + * afs_uint32 alternative vl port + * afs_uint32 count of vldb servers + * char[] cellname + * char[] linkedcell + * n * char[] hostnames + */ +afs_int32 +cm_IoctlNewCell2(struct cm_ioctl *ioctlp, struct cm_user *userp) +{ + afs_uint32 code = 0; + afs_uint32 flags = 0; + afs_uint32 fsport = 0; + afs_uint32 vlport = 0; + afs_uint32 i, host_count = 0; + char * cellname = NULL; + char * linked_cellname = NULL; + char *tp; + size_t tplen; + afs_uint32 *lp; + char * hostname[AFS_MAXHOSTS]; + size_t len; + + memset(hostname, 0, sizeof(hostname)); + + tp = ioctlp->inDatap; + tplen = ioctlp->inCopied; + lp = (afs_uint32 *)tp; + + if (tplen >= 4 * sizeof(afs_uint32)) { + flags = *lp++; + fsport = *lp++; + vlport = *lp++; + host_count = *lp++; + tp = (char *)lp; + tplen -= 4 * sizeof(afs_uint32); + } + + if ( FAILED(StringCbLength(tp, tplen, &len)) || + len + 1 > CELL_MAXNAMELEN) + return CM_ERROR_INVAL; + cellname = tp; + tp += len + 1; + tplen -= (len + 1); + + if ( FAILED(StringCbLength(tp, tplen, &len)) || + len + 1 > CELL_MAXNAMELEN) + return CM_ERROR_INVAL; + linked_cellname = tp; + tp += len + 1; + tplen -= (len + 1); + + if (!(flags & VIOC_NEWCELL2_FLAG_USEDNS)) { + for ( i=0; iparms[1].items; ti; ti=ti->next) { - thp = hostutil_GetHostByName(ti->data); - if (!thp) { - fprintf(stderr,"%s: Host %s not found in host table, skipping it.\n", - pn, ti->data); - } - else { -#if _MSC_VER < 1400 - memcpy(tp, thp->h_addr, sizeof(afs_int32)); -#else - err = memcpy_s(tp, sizeof(space) - (tp - space) * sizeof(char), thp->h_addr, sizeof(afs_int32)); - if ( err ) { - fprintf (stderr, "memcpy_s failure on tp"); - exit(1); - } -#endif - tp += sizeof(afs_int32); - } + if ( !IsAdmin() ) { + fprintf (stderr,"Permission denied: requires AFS Client Administrator access.\n"); + return EACCES; } + + /* if there is no cell specified, use old Windows behavior */ + if (as->parms[0].items == NULL) { + blob.in_size = 0; + blob.in = (char *) 0; + blob.out_size = AFS_PIOCTL_MAXSIZE; + blob.out = space; + + code = pioctl_utf8((char *) 0, VIOCNEWCELL, &blob, 1); + + if (code) { + Die(errno, (char *) 0); + return 1; + } + + printf("Cell servers information refreshed\n"); + return 0; + } else { + cellname = as->parms[0].items->data; + } + if (as->parms[2].items) { /* * Link the cell, for the purposes of volume location, to the specified * cell. */ - cellname = as->parms[2].items->data; + linked_cellname = as->parms[2].items->data; linkedstate = 1; } -#ifdef FS_ENABLE_SERVER_DEBUG_PORTS + if (as->parms[3].items) { - code = util_GetInt32(as->parms[3].items->data, &vlport); + code = util_GetInt32(as->parms[2].items->data, &vlport); if (code) { fprintf(stderr,"fs: bad integer specified for the fileserver port.\n"); return code; } } if (as->parms[4].items) { - code = util_GetInt32(as->parms[4].items->data, &fsport); + code = util_GetInt32(as->parms[3].items->data, &fsport); if (code) { fprintf(stderr,"fs: bad integer specified for the vldb server port.\n"); return code; } } -#endif - tp = (char *)(space + (AFS_MAXHOSTS+1) *sizeof(afs_int32)); - lp = (afs_int32 *)tp; + + if (as->parms[5].items) { + useregistry = 1; + } + + if (as->parms[6].items) { + usedns = 1; + } + + /* Count the number of hostnames */ + for (ti=as->parms[1].items; ti && count < AFS_MAXHOSTS; ti=ti->next, count++); + + if (!usedns && count == 0) { + fprintf( stderr, "fs: at least one vldb server must be specified."); + exit(1); + } + + if (count > AFS_MAXHOSTS) { + fprintf( stderr, "fs: at most %u servers may be specified.", AFS_MAXHOSTS); + exit(1); + } + + /* + * The pioctl data buffer consists of the following structure: + * + * afs_uint32 flags + * afs_uint32 alternative fs port + * afs_uint32 alternative vl port + * afs_uint32 count of vldb servers + * char[] cellname + * char[] linkedcell + * n * char[] hostnames + */ + + memset(space, 0, sizeof(space)); + tp = space; + lp = (afs_uint32 *)tp; + + /* flags */ + if (usedns) + *lp |= VIOC_NEWCELL2_FLAG_USEDNS; + + if (useregistry) + *lp |= VIOC_NEWCELL2_FLAG_USEREG; + + if (linkedstate) + *lp |= VIOC_NEWCELL2_FLAG_LINKED; + lp++; + + /* alt fs port */ *lp++ = fsport; + + /* alt vl port */ *lp++ = vlport; - *lp = linkedstate; - if( FAILED(StringCbCopyEx(space + ((AFS_MAXHOSTS+4) * sizeof(afs_int32)), sizeof(space) - (AFS_MAXHOSTS+4) * sizeof(afs_int32) - , as->parms[0].items->data, &tp, &destRemaining, STRSAFE_FILL_ON_FAILURE))) { - fprintf (stderr, "var - not enough space"); + + /* count of server names */ + *lp++ = count; + + /* Switch back to char pointer */ + tp = (char *)lp; + + /* Add nul-terminated cellname */ + destRemaining = sizeof(space) - (tp - space); + if( FAILED(StringCbCopyEx( tp, + destRemaining, + as->parms[0].items->data, + &tp, + &destRemaining, + STRSAFE_FILL_ON_FAILURE))) { + fprintf (stderr, " not enough space for cellname"); + exit(1); + } + /* Move beyond the terminating nul */ + tp++; + destRemaining -= sizeof(char); + + /* Add nul-terminated linkname */ + if( FAILED(StringCbCopyEx( tp, + destRemaining, + linkedstate ? linked_cellname : "", + &tp, + &destRemaining, + STRSAFE_FILL_ON_FAILURE))) { + fprintf (stderr, " not enough space for linked cellname"); exit(1); } - tp++; /* for null */ + /* Move beyond the terminating nul */ + tp++; destRemaining -= sizeof(char); - if (linkedstate) { - if( FAILED(StringCbCopyEx(tp, sizeof(space) - size, cellname, &destEnd, &destRemaining, STRSAFE_FILL_ON_FAILURE))) { - fprintf (tp, "space arr - not enough space"); + + /* Add the servers */ + for (ti=as->parms[1].items; ti; ti=ti->next) { + if( FAILED(StringCbCopyEx( tp, + destRemaining, + ti->data, + &tp, + &destRemaining, + STRSAFE_FILL_ON_FAILURE))) { + fprintf (stderr, " not enough space for server %s", ti->data); exit(1); - } - size += destEnd - tp + 1; + } + /* Move beyond the terminating nul */ + tp++; + destRemaining -= sizeof(char); } - blob.in_size = size; + + blob.in_size = (tp - space); blob.in = space; blob.out_size = 0; - code = pioctl_utf8(0, VIOCNEWCELL, &blob, 1); - if (code < 0) - Die(errno, 0); - return 0; -#else /* WIN32 */ - afs_int32 code; - struct ViceIoctl blob; - - if ( !IsAdmin() ) { - fprintf (stderr,"Permission denied: requires AFS Client Administrator access.\n"); - return EACCES; - } - - blob.in_size = 0; - blob.in = (char *) 0; - blob.out_size = AFS_PIOCTL_MAXSIZE; blob.out = space; - - code = pioctl_utf8((char *) 0, VIOCNEWCELL, &blob, 1); + code = pioctl_utf8(NULL, VIOCNEWCELL2, &blob, 1); if (code) { - Die(errno, (char *) 0); + Die(errno, as->parms[0].items->data); return 1; } - printf("Cell servers information refreshed\n"); + printf("Cell servers information for %s added or updated.\n", + as->parms[0].items->data); return 0; -#endif /* WIN32 */ } #ifndef WIN32 @@ -5694,12 +5762,10 @@ int wmain(int argc, wchar_t **wargv) cmd_CreateAlias(ts, "sq"); ts = cmd_CreateSyntax("newcell", NewCellCmd, NULL, "configure new cell"); -#ifndef WIN32 - cmd_AddParm(ts, "-name", CMD_SINGLE, 0, "cell name"); - cmd_AddParm(ts, "-servers", CMD_LIST, CMD_REQUIRED, "primary servers"); + cmd_AddParm(ts, "-name", CMD_SINGLE, CMD_OPTIONAL, "cell name"); + cmd_AddParm(ts, "-servers", CMD_LIST, CMD_OPTIONAL, "primary servers"); cmd_AddParm(ts, "-linkedcell", CMD_SINGLE, CMD_OPTIONAL, "linked cell name"); -#ifdef FS_ENABLE_SERVER_DEBUG_PORTS /* * Turn this on only if you wish to be able to talk to a server which is listening * on alternative ports. This is not intended for general use and may not be @@ -5708,8 +5774,10 @@ int wmain(int argc, wchar_t **wargv) */ cmd_AddParm(ts, "-fsport", CMD_SINGLE, CMD_OPTIONAL, "cell's fileserver port"); cmd_AddParm(ts, "-vlport", CMD_SINGLE, CMD_OPTIONAL, "cell's vldb server port"); -#endif + cmd_AddParm(ts, "-registry", CMD_FLAG, CMD_OPTIONAL, "add cell info to registry cellservdb"); + cmd_AddParm(ts, "-dns", CMD_FLAG, CMD_OPTIONAL, "force use of dns"); +#ifndef WIN32 ts = cmd_CreateSyntax("newalias", NewAliasCmd, NULL, "configure new cell alias"); cmd_AddParm(ts, "-alias", CMD_SINGLE, 0, "alias name"); diff --git a/src/WINNT/afsd/smb_iocons.h b/src/WINNT/afsd/smb_iocons.h index 9ecb139..ada8834 100644 --- a/src/WINNT/afsd/smb_iocons.h +++ b/src/WINNT/afsd/smb_iocons.h @@ -98,9 +98,14 @@ struct sbstruct { #define VIOC_SETOWNER 0x34 #define VIOC_SETGROUP 0x35 #define VIOC_FS_CMD 0x36 +#define VIOCNEWCELL2 0x37 #define VIOC_VOLSTAT_TEST 0x3F +#define VIOC_NEWCELL2_FLAG_LINKED 0x1 +#define VIOC_NEWCELL2_FLAG_USEDNS 0x2 +#define VIOC_NEWCELL2_FLAG_USEREG 0x4 + /* magic file name for ioctl opens */ #define CM_IOCTL_FILENAME "\\_._AFS_IOCTL_._" /* double backslashes for C compiler */ #define CM_IOCTL_FILENAME_NOSLASH "_._AFS_IOCTL_._" diff --git a/src/WINNT/afsd/smb_ioctl.c b/src/WINNT/afsd/smb_ioctl.c index b11268a..55b6bf9 100644 --- a/src/WINNT/afsd/smb_ioctl.c +++ b/src/WINNT/afsd/smb_ioctl.c @@ -89,6 +89,7 @@ smb_InitIoctl(void) smb_ioctlProcsp[VIOC_UNICODECTL] = smb_IoctlUnicodeControl; smb_ioctlProcsp[VIOC_SETOWNER] = smb_IoctlSetOwner; smb_ioctlProcsp[VIOC_SETGROUP] = smb_IoctlSetGroup; + smb_ioctlProcsp[VIOCNEWCELL2] = smb_IoctlNewCell2; } /* called to make a fid structure into an IOCTL fid structure */ @@ -1554,6 +1555,14 @@ smb_IoctlNewCell(struct smb_ioctl *ioctlp, struct cm_user *userp) } afs_int32 +smb_IoctlNewCell2(struct smb_ioctl *ioctlp, struct cm_user *userp) +{ + cm_SkipIoctlPath(&ioctlp->ioctl); + + return cm_IoctlNewCell2(&ioctlp->ioctl, userp); +} + +afs_int32 smb_IoctlGetWsCell(smb_ioctl_t *ioctlp, cm_user_t *userp) { cm_SkipIoctlPath(&ioctlp->ioctl); diff --git a/src/WINNT/afsd/smb_ioctl.h b/src/WINNT/afsd/smb_ioctl.h index 033533f..ba136d3 100644 --- a/src/WINNT/afsd/smb_ioctl.h +++ b/src/WINNT/afsd/smb_ioctl.h @@ -128,6 +128,8 @@ extern afs_int32 smb_IoctlGetCell(smb_ioctl_t *ioctlp, cm_user_t *userp); extern afs_int32 smb_IoctlNewCell(smb_ioctl_t *ioctlp, cm_user_t *userp); +extern afs_int32 smb_IoctlNewCell2(smb_ioctl_t *ioctlp, cm_user_t *userp); + extern afs_int32 smb_IoctlGetWsCell(smb_ioctl_t *ioctlp, cm_user_t *userp); extern afs_int32 smb_IoctlSysName(smb_ioctl_t *ioctlp, cm_user_t *userp); -- 1.9.4