2 * Copyright (c) 2007 Secure Endpoints Inc.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
10 * * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * * Neither the name of the Secure Endpoints Inc. nor the names of its
13 * contributors may be used to endorse or promote products derived
14 * from this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
20 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
23 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
24 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
25 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 /* This source file provides the declarations
30 * which specify the AFS Cache Manager Volume Status Event
34 #include <afs/param.h>
43 #include <WINNT/afsreg.h>
45 HMODULE hVolStatus = NULL;
46 dll_VolStatus_Funcs_t dll_funcs;
47 cm_VolStatus_Funcs_t cm_funcs;
49 /* This function is used to load any Volume Status Handlers
50 * and their associated function pointers.
53 cm_VolStatus_Initialization(void)
55 long (__fastcall * dll_VolStatus_Initialization)(dll_VolStatus_Funcs_t * dll_funcs, cm_VolStatus_Funcs_t *cm_funcs) = NULL;
59 char wd[MAX_PATH+1] = "";
61 code = RegOpenKeyEx(HKEY_LOCAL_MACHINE, AFSREG_CLT_SVC_PARAM_SUBKEY,
62 0, KEY_QUERY_VALUE, &parmKey);
63 if (code == ERROR_SUCCESS) {
64 dummyLen = sizeof(wd);
65 code = RegQueryValueEx(parmKey, "VolStatusHandler", NULL, NULL,
66 (BYTE *) &wd, &dummyLen);
67 RegCloseKey (parmKey);
70 if (code == ERROR_SUCCESS && wd[0])
71 hVolStatus = LoadLibrary(wd);
73 (FARPROC) dll_VolStatus_Initialization = GetProcAddress(hVolStatus, "@VolStatus_Initialization@8");
74 if (dll_VolStatus_Initialization) {
75 cm_funcs.version = CM_VOLSTATUS_FUNCS_VERSION;
76 cm_funcs.cm_VolStatus_Path_To_ID = cm_VolStatus_Path_To_ID;
77 cm_funcs.cm_VolStatus_Path_To_DFSlink = cm_VolStatus_Path_To_DFSlink;
79 code = dll_VolStatus_Initialization(&dll_funcs, &cm_funcs);
82 if (dll_VolStatus_Initialization == NULL || code != 0 ||
83 dll_funcs.version != DLL_VOLSTATUS_FUNCS_VERSION) {
84 FreeLibrary(hVolStatus);
93 /* This function is used to unload any Volume Status Handlers
94 * that were loaded during initialization.
97 cm_VolStatus_Finalize(void)
99 if (hVolStatus == NULL)
102 FreeLibrary(hVolStatus);
107 /* This function notifies the Volume Status Handlers that the
108 * AFS client service has started. If the network is started
109 * at this point we call cm_VolStatus_Network_Started().
112 cm_VolStatus_Service_Started(void)
116 if (hVolStatus == NULL)
119 code = dll_funcs.dll_VolStatus_Service_Started();
120 if (code == 0 && smb_IsNetworkStarted())
121 code = dll_funcs.dll_VolStatus_Network_Started(cm_NetbiosName, cm_NetbiosName);
126 /* This function notifies the Volume Status Handlers that the
127 * AFS client service is stopping.
130 cm_VolStatus_Service_Stopped(void)
134 if (hVolStatus == NULL)
137 code = dll_funcs.dll_VolStatus_Service_Stopped();
143 /* This function notifies the Volume Status Handlers that the
144 * AFS client service is accepting network requests using the
145 * specified netbios names.
149 cm_VolStatus_Network_Started(const char * netbios32, const char * netbios64)
151 cm_VolStatus_Network_Started(const char * netbios)
156 if (hVolStatus == NULL)
160 code = dll_funcs.dll_VolStatus_Network_Started(netbios32, netbios64);
162 code = dll_funcs.dll_VolStatus_Network_Started(netbios, netbios);
168 /* This function notifies the Volume Status Handlers that the
169 * AFS client service is no longer accepting network requests
170 * using the specified netbios names
174 cm_VolStatus_Network_Stopped(const char * netbios32, const char * netbios64)
176 cm_VolStatus_Network_Stopped(const char * netbios)
181 if (hVolStatus == NULL)
185 code = dll_funcs.dll_VolStatus_Network_Stopped(netbios32, netbios64);
187 code = dll_funcs.dll_VolStatus_Network_Stopped(netbios, netbios);
193 /* This function is called when the IP address list changes.
194 * Volume Status Handlers can use this notification as a hint
195 * that it might be possible to determine volume IDs for paths
196 * that previously were not accessible.
199 cm_VolStatus_Network_Addr_Change(void)
203 if (hVolStatus == NULL)
206 code = dll_funcs.dll_VolStatus_Network_Addr_Change();
211 /* This function notifies the Volume Status Handlers that the
212 * state of the specified cell.volume has changed.
215 cm_VolStatus_Change_Notification(afs_uint32 cellID, afs_uint32 volID, enum volstatus status)
219 if (hVolStatus == NULL)
222 code = dll_funcs.dll_VolStatus_Change_Notification(cellID, volID, status);
229 cm_VolStatus_Path_To_ID(const char * share, const char * path, afs_uint32 * cellID, afs_uint32 * volID)
235 if (cellID == NULL || volID == NULL)
236 return CM_ERROR_INVAL;
241 code = cm_NameI(cm_data.rootSCachep, (char *)path, CM_FLAG_FOLLOW, cm_rootUserp, (char *)share, &req, &scp);
245 lock_ObtainMutex(&scp->mx);
246 code = cm_SyncOp(scp, NULL,cm_rootUserp, &req, 0,
247 CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
249 lock_ReleaseMutex(&scp->mx);
250 cm_ReleaseSCache(scp);
254 cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
256 *cellID = scp->fid.cell;
257 *volID = scp->fid.volume;
259 lock_ReleaseMutex(&scp->mx);
260 cm_ReleaseSCache(scp);
266 cm_VolStatus_Path_To_DFSlink(const char * share, const char * path, afs_uint32 *pBufSize, char *pBuffer)
273 if (pBufSize == NULL || (pBuffer == NULL && *pBufSize != 0))
274 return CM_ERROR_INVAL;
278 code = cm_NameI(cm_data.rootSCachep, (char *)path, CM_FLAG_FOLLOW, cm_rootUserp, (char *)share, &req, &scp);
282 lock_ObtainMutex(&scp->mx);
283 code = cm_SyncOp(scp, NULL, cm_rootUserp, &req, 0,
284 CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
286 lock_ReleaseMutex(&scp->mx);
287 cm_ReleaseSCache(scp);
291 cm_SyncOpDone(scp, NULL, CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS);
293 if (scp->fileType != CM_SCACHETYPE_DFSLINK)
294 return CM_ERROR_NOT_A_DFSLINK;
296 len = strlen(scp->mountPointStringp) + 1;
299 else if (*pBufSize >= len) {
300 strcpy(pBuffer, scp->mountPointStringp);
303 code = CM_ERROR_TOOBIG;
305 lock_ReleaseMutex(&scp->mx);
306 cm_ReleaseSCache(scp);