Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

558 lines
20 KiB

  1. /******************************************************************************
  2. Copyright (c) Microsoft Corporation
  3. Module Name:
  4. Disconnect.cpp
  5. Abstract:
  6. Disconnects one or more open files
  7. Author:
  8. Akhil Gokhale (akhil.gokhale@wipro.com) 1-Nov-2000
  9. Revision History:
  10. Akhil Gokhale (akhil.gokhale@wipro.com) 1-Nov-2000 : Created It.
  11. ******************************************************************************/
  12. //include headers
  13. #include "pch.h"
  14. #include "Disconnect.h"
  15. /*-----------------------------------------------------------------------------
  16. Routine Description:
  17. Disconnects one or more openfiles
  18. Arguments:
  19. [in] pszServer - remote server name
  20. [in] pszID - Open file ids
  21. [in] pszAccessedby - Name of user name who access the file
  22. [in] pszOpenmode - accessed mode
  23. [in] pszOpenFile - Open file name
  24. Returned Value:
  25. - TRUE for success exit
  26. - FALSE for failure exit
  27. -----------------------------------------------------------------------------*/
  28. BOOL
  29. DisconnectOpenFile( PTCHAR pszServer,
  30. PTCHAR pszID,
  31. PTCHAR pszAccessedby,
  32. PTCHAR pszOpenmode,
  33. PTCHAR pszOpenFile )
  34. {
  35. // local variables to this function
  36. BOOL bResult = FALSE;// Stores fuctions return value status.
  37. DWORD dwEntriesRead = 0;// Receives the count of elements actually
  38. // enumerated by "NetFileEnum" function
  39. DWORD dwTotalEntries = 0;//Receives the total number of entries that could
  40. //have been enumerated from the current
  41. //resume position by "NetFileEnum" function
  42. DWORD dwResumeHandle = 0;//Contains a resume handle which is used to
  43. //continue an existing file search.
  44. //The handle should be zero on the first call and
  45. //left unchanged for subsequent calls.
  46. //If resume_handle is NULL,
  47. //then no resume handle is stored. This variable
  48. // used in calling "NetFileEnum" function.
  49. LPFILE_INFO_3 pFileInfo3_1 = NULL; //LPFILE_INFO_3 structure contains the
  50. //identification number and other
  51. //pertinent information about files,
  52. //devices, and pipes.
  53. DWORD dwError = 0;//Contains return value for "NetFileEnum" function
  54. NET_API_STATUS nStatus = 0;// Stores return value for NetFileClose functin
  55. TCHAR szResult[(MAX_RES_STRING*2) + 1] = NULL_STRING;
  56. AFP_FILE_INFO* pFileInfo = NULL;
  57. DWORD hEnumHandle = 0;
  58. HRESULT hr = S_OK;
  59. NET_API_STATUS retval = NERR_Success;
  60. AFP_SERVER_HANDLE ulSFMServerConnection = 0;
  61. TCHAR szDllPath[MAX_PATH+1] = NULL_STRING;// buffer for Windows directory
  62. HMODULE hModule = 0; // To store retval for LoadLibrary
  63. DWORD dwConnectionId = 0;
  64. typedef DWORD (*AFPCONNECTIONCLOSEPROC) (AFP_SERVER_HANDLE,DWORD); // Function pointer
  65. typedef DWORD (*CONNECTPROC) (LPWSTR,PAFP_SERVER_HANDLE);// Function pointer
  66. typedef DWORD (*FILEENUMPROC)(AFP_SERVER_HANDLE,LPBYTE*,DWORD,LPDWORD,LPDWORD,LPDWORD);
  67. AFPCONNECTIONCLOSEPROC AfpAdminFileClose = NULL;
  68. CONNECTPROC AfpAdminConnect = NULL;
  69. FILEENUMPROC AfpAdminFileEnum = NULL;// Function Pointer
  70. //varibles to store whether the given credentials are matching with the
  71. //got credentials.
  72. BOOL bId = FALSE;
  73. BOOL bAccessedBy = FALSE;
  74. BOOL bOpenmode = FALSE;
  75. BOOL bOpenfile = FALSE;
  76. BOOL bIfatleast = FALSE;
  77. do
  78. {
  79. // Get the block of files
  80. dwError = NetFileEnum( pszServer,
  81. NULL,
  82. NULL,
  83. 3,
  84. (LPBYTE *)&pFileInfo3_1,
  85. MAX_PREFERRED_LENGTH,
  86. &dwEntriesRead,
  87. &dwTotalEntries,
  88. (PDWORD_PTR)&dwResumeHandle );
  89. if(dwError == ERROR_ACCESS_DENIED)
  90. {
  91. SetLastError(ERROR_ACCESS_DENIED);
  92. DISPLAY_MESSAGE(stderr,GetResString(IDS_ID_SHOW_ERROR));
  93. ShowLastError(stderr);
  94. return FALSE;
  95. }
  96. if( dwError == NERR_Success || dwError == ERROR_MORE_DATA )
  97. {
  98. for ( DWORD dwFile = 0;
  99. dwFile < dwEntriesRead;
  100. dwFile++, pFileInfo3_1++ )
  101. {
  102. //Check whether the got open file is file or names pipe.
  103. // If named pipe leave it. As this utility do not
  104. // disconnect Named pipe
  105. if ( IsNamedPipePath(pFileInfo3_1->fi3_pathname ) )
  106. {
  107. continue;
  108. }
  109. else//Not a named pipe. is a file
  110. {
  111. bId = IsSpecifiedID(pszID,pFileInfo3_1->fi3_id);
  112. bAccessedBy = IsSpecifiedAccessedBy(pszAccessedby,
  113. pFileInfo3_1->fi3_username);
  114. bOpenmode = IsSpecifiedOpenmode(pszOpenmode,
  115. pFileInfo3_1->fi3_permissions);
  116. bOpenfile = IsSpecifiedOpenfile(pszOpenFile,
  117. pFileInfo3_1->fi3_pathname);
  118. // Proceed for dicconecting the open file only if
  119. // all previous fuction returns true. This insures that
  120. // user preference is taken care.
  121. if( bId &&
  122. bAccessedBy &&
  123. bOpenmode &&
  124. bOpenfile)
  125. {
  126. bIfatleast = TRUE;
  127. memset( szResult, 0, (((MAX_RES_STRING*2) + 1) *
  128. sizeof( TCHAR )) );
  129. //The NetFileClose function forces a resource to close.
  130. nStatus = NetFileClose(pszServer,
  131. pFileInfo3_1->fi3_id);
  132. if(nStatus == NERR_Success)
  133. {
  134. // Create the output message string as File
  135. // is successfully deleted.
  136. // Output string will be :
  137. // SUCCESS: Connection to openfile "filename"
  138. // has been terminated.
  139. bResult = TRUE;
  140. FORMAT_STRING(szResult,DISCONNECTED_SUCCESSFULLY,pFileInfo3_1->fi3_pathname);
  141. DISPLAY_MESSAGE(stdout, szResult);
  142. }
  143. else
  144. {
  145. // As unable to disconnect the openfile make
  146. // output message as
  147. // ERROR: could not dissconnect "filename".
  148. bResult = FALSE;
  149. FORMAT_STRING(szResult,DISCONNECT_UNSUCCESSFUL,pFileInfo3_1->fi3_pathname);
  150. DISPLAY_MESSAGE(stderr, szResult);
  151. }
  152. // Display output result as previously constructed.
  153. }//If bId...
  154. }//else part of is named pipe
  155. }
  156. }
  157. } while ( dwError == ERROR_MORE_DATA );
  158. // Free the block
  159. if( pFileInfo3_1 !=NULL)
  160. {
  161. NetApiBufferFree( pFileInfo3_1 );
  162. pFileInfo3_1 = NULL;
  163. }
  164. // Now disconnect files for MAC OS
  165. do
  166. {
  167. // DLL required is stored always in \windows\system32 directory....
  168. // so get windows directory first.
  169. if(GetSystemDirectory(szDllPath, MAX_PATH)!= 0)
  170. {
  171. lstrcat(szDllPath,MAC_DLL_FILE_NAME);
  172. hModule = ::LoadLibrary (szDllPath);
  173. if(hModule==NULL)
  174. {
  175. DISPLAY_MESSAGE(stderr,GetResString(IDS_ID_SHOW_ERROR));
  176. ShowLastError(stderr); // Shows the error string set by API function.
  177. return FALSE;
  178. }
  179. }
  180. else
  181. {
  182. DISPLAY_MESSAGE(stderr,GetResString(IDS_ID_SHOW_ERROR));
  183. ShowLastError(stderr); // Shows the error string set by API function.
  184. return FALSE;
  185. }
  186. AfpAdminConnect = (CONNECTPROC)::GetProcAddress (hModule,"AfpAdminConnect");
  187. AfpAdminFileClose = (AFPCONNECTIONCLOSEPROC)::GetProcAddress (hModule,"AfpAdminFileClose");
  188. AfpAdminFileEnum = (FILEENUMPROC)::GetProcAddress (hModule,"AfpAdminFileEnum");
  189. // Check if all function pointer successfully taken from DLL
  190. // if not show error message and exit
  191. if((AfpAdminFileClose== NULL)||
  192. (AfpAdminConnect == NULL)||
  193. (AfpAdminFileEnum == NULL))
  194. {
  195. DISPLAY_MESSAGE(stderr,GetResString(IDS_ID_SHOW_ERROR));
  196. ShowLastError(stderr); // Shows the error string set by API function.
  197. FREE_LIBRARY(hModule);
  198. return FALSE;
  199. }
  200. // Connection ID is requered for AfpAdminFileEnum function so
  201. // connect to server to get connect id...
  202. DWORD retval_connect = AfpAdminConnect(const_cast<LPWSTR>(pszServer),
  203. &ulSFMServerConnection );
  204. if(retval_connect!=0)
  205. {
  206. DISPLAY_MESSAGE(stderr,GetResString(IDS_ID_SHOW_ERROR));
  207. ShowLastError(stderr); // Shows the error string set by API function.
  208. FREE_LIBRARY(hModule);
  209. return FALSE;
  210. }
  211. dwError = AfpAdminFileEnum( ulSFMServerConnection,
  212. (PBYTE*)&pFileInfo,
  213. (DWORD)-1L,
  214. &dwEntriesRead,
  215. &dwTotalEntries,
  216. &hEnumHandle );
  217. if(dwError == ERROR_ACCESS_DENIED)
  218. {
  219. SetLastError(ERROR_ACCESS_DENIED);
  220. DISPLAY_MESSAGE(stderr,GetResString(IDS_ID_SHOW_ERROR));
  221. ShowLastError(stderr);
  222. FREE_LIBRARY(hModule);
  223. return FALSE;
  224. }
  225. if( dwError == NERR_Success || dwError == ERROR_MORE_DATA )
  226. {
  227. for ( DWORD dwFile = 0;
  228. dwFile < dwEntriesRead;
  229. dwFile++, pFileInfo++ )
  230. {
  231. //Check whether the got open file is file or names pipe.
  232. // If named pipe leave it. As this utility do not
  233. // disconnect Named pipe
  234. if ( IsNamedPipePath(pFileInfo->afpfile_path ) )
  235. {
  236. continue;
  237. }
  238. else//Not a named pipe. is a file
  239. {
  240. bId = IsSpecifiedID(pszID,pFileInfo->afpfile_id );
  241. bAccessedBy = IsSpecifiedAccessedBy(pszAccessedby,
  242. pFileInfo->afpfile_username );
  243. bOpenmode = IsSpecifiedOpenmode(pszOpenmode,
  244. pFileInfo->afpfile_open_mode);
  245. bOpenfile = IsSpecifiedOpenfile(pszOpenFile,
  246. pFileInfo->afpfile_path);
  247. // Proceed for dicconecting the open file only if
  248. // all previous fuction returns true. This insures that
  249. // user preference is taken care.
  250. if( bId &&
  251. bAccessedBy &&
  252. bOpenmode &&
  253. bOpenfile)
  254. {
  255. bIfatleast = TRUE;
  256. memset( szResult, 0, (((MAX_RES_STRING*2) + 1) *
  257. sizeof( TCHAR )) );
  258. nStatus = AfpAdminFileClose(ulSFMServerConnection,
  259. pFileInfo->afpfile_id);
  260. if(nStatus == NERR_Success)
  261. {
  262. // Create the output message string as File
  263. // is successfully deleted.
  264. // Output string will be :
  265. // SUCCESS: Connection to openfile "filename"
  266. // has been terminated.
  267. bResult = TRUE;
  268. //lstrcpy(szTemp,DISCONNECTED_SUCCESSFULLY);
  269. //lstrcat(szResult,pFileInfo3_1->fi3_pathname);
  270. //lstrcat(szResult,HAS_BEEN_TERMINATED);
  271. FORMAT_STRING(szResult,DISCONNECTED_SUCCESSFULLY,pFileInfo->afpfile_path);
  272. DISPLAY_MESSAGE(stdout, szResult);
  273. bResult = TRUE;
  274. }
  275. else
  276. {
  277. // As unable to disconnect the openfile make
  278. // output message as
  279. // ERROR: could not dissconnect "filename".
  280. bResult = FALSE;
  281. FORMAT_STRING(szResult,DISCONNECT_UNSUCCESSFUL,pFileInfo3_1->fi3_pathname);
  282. DISPLAY_MESSAGE(stderr, szResult);
  283. }
  284. }//If bId...
  285. }//else part of is named pipe
  286. }
  287. }
  288. } while ( dwError == ERROR_MORE_DATA );
  289. if(bIfatleast == FALSE)// As not a single open file disconnected
  290. // show Info. message as
  291. // INFO: No. open files found.
  292. {
  293. ShowMessage(stdout,GetResString(IDS_NO_D_OPENFILES));
  294. }
  295. // Free the block
  296. if( pFileInfo !=NULL)
  297. {
  298. NetApiBufferFree( pFileInfo);
  299. pFileInfo = NULL;
  300. }
  301. FREE_LIBRARY(hModule);
  302. return TRUE;
  303. }
  304. /*-----------------------------------------------------------------------------
  305. Routine Description:
  306. Tests whether the given file path is namedpipe path or a file path
  307. Arguments:
  308. [in] pszwFilePath -- Null terminated string specifying the path name
  309. Returned Value:
  310. TRUE - if it is a named pipe path
  311. FALSE - if it is a file path
  312. -----------------------------------------------------------------------------*/
  313. BOOL
  314. IsNamedPipePath(LPWSTR pszwFilePath)
  315. {
  316. LPWSTR pwszSubString = NULL;
  317. pwszSubString = wcsstr(pszwFilePath, PIPE_STRING);//Search PIPE_STRING
  318. // If PIPE_STRING found then return TRUE else FALSE.
  319. if( pwszSubString == NULL)
  320. {
  321. return FALSE;
  322. }
  323. return TRUE;
  324. }//IsNamedPipePath
  325. /*-----------------------------------------------------------------------------
  326. Routine Description:
  327. Tests whether the user specified open file id is equivalent to the api
  328. returned id.
  329. Arguments:
  330. [in] pszId -Null terminated string specifying the user
  331. specified fil ID
  332. [in] dwId -current file ID.
  333. Returned Value:
  334. TRUE - if pszId is * or equal to dwId
  335. FALSE - otherwise
  336. -----------------------------------------------------------------------------*/
  337. BOOL
  338. IsSpecifiedID(LPTSTR pszId, DWORD dwId)
  339. {
  340. // Check if WILD card is given OR no id is given OR given id and
  341. // id returned by api is similar. In any of the case return TRUE.
  342. if((lstrcmp(pszId, WILD_CARD) == 0) ||
  343. (lstrlen(pszId) == 0)||
  344. ((DWORD)(_ttol(pszId)) == dwId))
  345. {
  346. return TRUE;
  347. }
  348. return FALSE;
  349. }//IsSpecifiedID
  350. /*-----------------------------------------------------------------------------
  351. Routine Description:
  352. Tests whether the user specified accessed open file username is equivalent to
  353. the api returned username.
  354. Arguments:
  355. [in] pszAccessedby - Null terminated string specifying the
  356. accessedby username
  357. [in] pszwAccessedby - Null terminated string specifying the api
  358. returned username.
  359. Returned Value:
  360. TRUE - if pszAccessedby is * or equal to pszwAccessedby
  361. FALSE - Otherwise
  362. -----------------------------------------------------------------------------*/
  363. BOOL
  364. IsSpecifiedAccessedBy(LPTSTR pszAccessedby, LPWSTR pszwAccessedby)
  365. {
  366. // Check if WILD card is given OR non - existance of username OR given
  367. // username and username returned by api is similar. In any of the case
  368. // return TRUE.
  369. if((lstrcmp(pszAccessedby, WILD_CARD) == 0) ||
  370. (lstrlen(pszAccessedby) == 0) ||
  371. (lstrcmpi(pszAccessedby,pszwAccessedby)==0))
  372. {
  373. return TRUE;
  374. }
  375. return FALSE;
  376. }//IsSpecifiedAccessedBy
  377. /*-----------------------------------------------------------------------------
  378. Routine Description:
  379. Tests whether the user specified open mode is equivalent to the api returned
  380. openmode
  381. Arguments:
  382. [in] pszOpenmode - Null terminated string specifying the openmode
  383. [in] dwOpenmode - The api returned open mode.
  384. Returned Value:
  385. TRUE - if pszOpenmode is * or equal to dwOpenmode
  386. FALSE - otherwise
  387. -----------------------------------------------------------------------------*/
  388. BOOL
  389. IsSpecifiedOpenmode(LPTSTR pszOpenmode, DWORD dwOpenmode)
  390. {
  391. // Check for WILD card if given OR if no open mode given . In both case
  392. // return TRUE.
  393. if((lstrcmp(pszOpenmode, WILD_CARD) == 0) ||
  394. (lstrlen(pszOpenmode) == 0))
  395. {
  396. return TRUE;
  397. }
  398. // Check if READ mode is given as String .
  399. if(CompareString(LOCALE_SYSTEM_DEFAULT,
  400. NORM_IGNORECASE,
  401. pszOpenmode,
  402. -1,
  403. READ_MODE,
  404. -1)== CSTR_EQUAL)
  405. {
  406. // check that only READ mode only with dwOpenmode variable which is
  407. // returned by api.
  408. if((PERM_FILE_READ == (dwOpenmode & PERM_FILE_READ)) &&
  409. (PERM_FILE_WRITE != (dwOpenmode & PERM_FILE_WRITE)))
  410. {
  411. return TRUE;
  412. }
  413. }
  414. // Check if write mode is given.
  415. else if(CompareString(LOCALE_SYSTEM_DEFAULT, NORM_IGNORECASE,
  416. pszOpenmode,-1,WRITE_MODE,-1) == CSTR_EQUAL)
  417. {
  418. // check that only WRITE mode only with dwOpenmode variable which is
  419. // returned by api.
  420. if((PERM_FILE_WRITE == (dwOpenmode & PERM_FILE_WRITE)) &&
  421. (PERM_FILE_READ != (dwOpenmode & PERM_FILE_READ)))
  422. {
  423. return TRUE;
  424. }
  425. }
  426. else if(CompareString(LOCALE_SYSTEM_DEFAULT, NORM_IGNORECASE,
  427. pszOpenmode,-1,READ_WRITE_MODE,-1) == CSTR_EQUAL)
  428. {
  429. if((PERM_FILE_READ == (dwOpenmode & PERM_FILE_READ)) &&
  430. (PERM_FILE_WRITE == (dwOpenmode & PERM_FILE_WRITE)))
  431. {
  432. return TRUE;
  433. }
  434. }
  435. else if(CompareString(LOCALE_SYSTEM_DEFAULT, NORM_IGNORECASE,
  436. pszOpenmode,-1,WRITE_READ_MODE,-1) == CSTR_EQUAL)
  437. {
  438. if((PERM_FILE_WRITE == (dwOpenmode & PERM_FILE_WRITE)) &&
  439. (PERM_FILE_READ == (dwOpenmode & PERM_FILE_READ)))
  440. {
  441. return TRUE;
  442. }
  443. }
  444. // Given string does not matches with predefined Strings..
  445. // return FALSE.
  446. return FALSE;
  447. }
  448. /*-----------------------------------------------------------------------------
  449. Routine Description:
  450. Tests whether the user specified open file is equalant to the api returned
  451. open file.
  452. Arguments:
  453. [in] pszOpenfile - Null terminated string specifying the open
  454. file
  455. [in] pszwOpenfile - Null terminated string specifying the api
  456. returned open file.
  457. Returned Value:
  458. TRUE - if pszOpenfile is * or equal to pszwOpenfile
  459. FALSE - otherwise
  460. -----------------------------------------------------------------------------*/
  461. BOOL
  462. IsSpecifiedOpenfile(LPTSTR pszOpenfile, LPWSTR pszwOpenfile)
  463. {
  464. // Check for WILD card if given OR no open file specified OR
  465. // open file given by user matches with open file returned by api.
  466. // In all cases return TRUE.
  467. if((lstrcmp(pszOpenfile, WILD_CARD) == 0)||
  468. (lstrlen(pszOpenfile) == 0) ||
  469. (lstrcmpi(pszwOpenfile,pszOpenfile)==0))
  470. {
  471. return TRUE;
  472. }
  473. return FALSE;
  474. }//IsSpecifiedOpenfile