Leaked source code of windows server 2003
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.

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