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.

1546 lines
50 KiB

  1. /*++
  2. Copyright (C) 1993 Microsoft Corporation
  3. Module Name:
  4. NWAPI32.C
  5. Abstract:
  6. This module contains the NetWare(R) SDK support to routines
  7. into the NetWare redirector
  8. Author:
  9. Chris Sandys (a-chrisa) 09-Sep-1993
  10. Revision History:
  11. Chuck Y. Chan (chuckc) 02/06/94 Moved to NWCS. Make it more NT like.
  12. Chuck Y. Chan (chuckc) 02/27/94 Clear out old code.
  13. Make logout work.
  14. Check for error in many places.
  15. Dont hard code strings.
  16. Remove non compatible parameters.
  17. Lotsa other cleanup.
  18. Tommy R. Evans (tommye) 04/21/00 Added two routines:
  19. NwNdsObjectHandleToConnHandle()
  20. NwNdsConnHandleFree()
  21. --*/
  22. #include "procs.h"
  23. #include "nwapi32.h"
  24. #include <nds32.h>
  25. #include <stdio.h>
  26. //
  27. // Define structure for internal use. Our handle passed back from attach to
  28. // file server will be pointer to this. We keep server string around for
  29. // discnnecting from the server on logout. The structure is freed on detach.
  30. // Callers should not use this structure but treat pointer as opaque handle.
  31. //
  32. typedef struct _NWC_SERVER_INFO {
  33. HANDLE hConn ;
  34. UNICODE_STRING ServerString ;
  35. } NWC_SERVER_INFO, *PNWC_SERVER_INFO ;
  36. //
  37. // define define categories of errors
  38. //
  39. typedef enum _NCP_CLASS {
  40. NcpClassConnect,
  41. NcpClassBindery,
  42. NcpClassDir
  43. } NCP_CLASS ;
  44. //
  45. // define error mapping structure
  46. //
  47. typedef struct _NTSTATUS_TO_NCP {
  48. NTSTATUS NtStatus ;
  49. NWCCODE NcpCode ;
  50. } NTSTATUS_TO_NCP, *LPNTSTATUS_TO_NCP ;
  51. //
  52. // Error mappings for directory errors
  53. //
  54. NTSTATUS_TO_NCP MapNcpDirErrors[] =
  55. {
  56. {STATUS_NO_SUCH_DEVICE, VOLUME_DOES_NOT_EXIST},
  57. {STATUS_INVALID_HANDLE, BAD_DIRECTORY_HANDLE},
  58. {STATUS_OBJECT_PATH_NOT_FOUND, INVALID_PATH},
  59. {STATUS_UNSUCCESSFUL, INVALID_PATH},
  60. {STATUS_NO_MORE_ENTRIES, NO_SUCH_OBJECT},
  61. {STATUS_ACCESS_DENIED, NO_OBJECT_READ_PRIVILEGE},
  62. {STATUS_INSUFF_SERVER_RESOURCES, SERVER_OUT_OF_MEMORY},
  63. { 0, 0 }
  64. } ;
  65. //
  66. // Error mappings for connect errors
  67. //
  68. NTSTATUS_TO_NCP MapNcpConnectErrors[] =
  69. {
  70. {STATUS_UNSUCCESSFUL, INVALID_CONNECTION},
  71. {STATUS_ACCESS_DENIED, NO_OBJECT_READ_PRIVILEGE},
  72. {STATUS_NO_MORE_ENTRIES, UNKNOWN_FILE_SERVER},
  73. {STATUS_INSUFF_SERVER_RESOURCES, SERVER_OUT_OF_MEMORY},
  74. { 0, 0 }
  75. } ;
  76. //
  77. // Error mappings for bindery errors
  78. //
  79. NTSTATUS_TO_NCP MapNcpBinderyErrors[] =
  80. {
  81. {STATUS_ACCESS_DENIED, NO_OBJECT_READ_PRIVILEGE},
  82. {STATUS_NO_MORE_ENTRIES, UNKNOWN_FILE_SERVER},
  83. {STATUS_NO_MORE_ENTRIES, NO_SUCH_OBJECT},
  84. {STATUS_INVALID_PARAMETER, NO_SUCH_PROPERTY},
  85. {STATUS_UNSUCCESSFUL, INVALID_CONNECTION},
  86. {STATUS_INSUFF_SERVER_RESOURCES, SERVER_OUT_OF_MEMORY},
  87. {STATUS_NO_SUCH_DEVICE, VOLUME_DOES_NOT_EXIST},
  88. {STATUS_INVALID_HANDLE, BAD_DIRECTORY_HANDLE},
  89. {STATUS_OBJECT_PATH_NOT_FOUND, INVALID_PATH},
  90. // {0xC0010001, INVALID_CONNECTION},
  91. // {0xC0010096, SERVER_OUT_OF_MEMORY},
  92. // {0xC0010098, VOLUME_DOES_NOT_EXIST},
  93. // {0xC001009B, BAD_DIRECTORY_HANDLE},
  94. // {0xC001009C, INVALID_PATH},
  95. // {0xC00100FB, NO_SUCH_PROPERTY},
  96. // {0xC00100FC, NO_SUCH_OBJECT},
  97. { 0, 0 }
  98. } ;
  99. //
  100. // Forwards
  101. //
  102. DWORD
  103. CancelAllConnections(
  104. LPWSTR pszServer
  105. );
  106. NWCCODE
  107. MapNtStatus(
  108. const NTSTATUS ntstatus,
  109. const NCP_CLASS ncpclass
  110. );
  111. DWORD
  112. SetWin32ErrorFromNtStatus(
  113. NTSTATUS NtStatus
  114. ) ;
  115. DWORD
  116. szToWide(
  117. LPWSTR lpszW,
  118. LPCSTR lpszC,
  119. INT nSize
  120. );
  121. //
  122. // Static functions used internally
  123. //
  124. LPSTR
  125. NwDupStringA(
  126. const LPSTR lpszA,
  127. WORD length
  128. )
  129. {
  130. LPSTR lpRet;
  131. //
  132. // Allocate memory
  133. //
  134. lpRet = LocalAlloc( LMEM_FIXED|LMEM_ZEROINIT , length );
  135. if(lpRet == NULL) return(NULL);
  136. //
  137. // Dupulicate string
  138. //
  139. memcpy( (LPVOID)lpRet, (LPVOID)lpszA, length );
  140. return(lpRet);
  141. }
  142. VOID
  143. MapSpecialJapaneseChars(
  144. LPSTR lpszA,
  145. WORD length
  146. )
  147. {
  148. LCID lcid;
  149. //
  150. // Netware Japanese version The following character is replaced with another one
  151. // if the string is for File Name only when sendding from Client to Server.
  152. //
  153. // any char, even DBCS trailByte.
  154. //
  155. // SJIS+0xBF -> 0x10
  156. // SJIS+0xAE -> 0x11
  157. // SJIS+0xAA -> 0x12
  158. //
  159. // DBCS TrailByte only.
  160. //
  161. // SJIS+0x5C -> 0x13
  162. //
  163. // Get system locale and language ID in Kernel mode in order to
  164. // distinguish the currently running system.
  165. NtQueryDefaultLocale( TRUE, &lcid );
  166. if (! (PRIMARYLANGID(lcid) == LANG_JAPANESE ||
  167. PRIMARYLANGID(lcid) == LANG_KOREAN ||
  168. PRIMARYLANGID(lcid) == LANG_CHINESE) ) {
  169. return;
  170. }
  171. if(lpszA == NULL)
  172. return;
  173. if( PRIMARYLANGID(lcid) == LANG_JAPANESE ) {
  174. while( length ) {
  175. if( IsDBCSLeadByte(*lpszA) && (length >= 2) ) {
  176. // Adding length>=2 ensure the Lead Byte is followed by
  177. // a trail byte , Fix bug #102729
  178. //
  179. // This is a DBCS character, check trailbyte is 0x5C or not.
  180. //
  181. lpszA++;
  182. length--;
  183. if( *lpszA == 0x5C ) {
  184. *lpszA = (UCHAR)0x13;
  185. }
  186. }
  187. switch( (UCHAR) *lpszA ) {
  188. case 0xBF :
  189. *lpszA = (UCHAR)0x10;
  190. break;
  191. case 0xAE :
  192. *lpszA = (UCHAR)0x11;
  193. break;
  194. case 0xAA :
  195. *lpszA = (UCHAR)0x12;
  196. break;
  197. }
  198. //
  199. // next char
  200. //
  201. lpszA++;
  202. length--;
  203. }
  204. }
  205. else if (PRIMARYLANGID(lcid) == LANG_CHINESE ||
  206. PRIMARYLANGID(lcid) == LANG_KOREAN) {
  207. while( length ) {
  208. if( IsDBCSLeadByte(*lpszA) && *(lpszA+1) == 0x5C ) {
  209. *(lpszA+1) = (UCHAR)0x13;
  210. }
  211. switch( (UCHAR) *lpszA ) {
  212. case 0xBF :
  213. *lpszA = (UCHAR)0x10;
  214. break;
  215. case 0xAE :
  216. *lpszA = (UCHAR)0x11;
  217. break;
  218. case 0xAA :
  219. *lpszA = (UCHAR)0x12;
  220. break;
  221. }
  222. //
  223. // next char
  224. //
  225. lpszA++;
  226. length--;
  227. }
  228. }
  229. }
  230. VOID
  231. UnmapSpecialJapaneseChars(
  232. LPSTR lpszA,
  233. WORD length
  234. )
  235. {
  236. LCID lcid;
  237. //
  238. // Get system locale and language ID in Kernel mode in order to
  239. // distinguish the currently running system.
  240. //
  241. NtQueryDefaultLocale( TRUE, &lcid );
  242. if (! (PRIMARYLANGID(lcid) == LANG_JAPANESE ||
  243. PRIMARYLANGID(lcid) == LANG_KOREAN ||
  244. PRIMARYLANGID(lcid) == LANG_CHINESE) ) {
  245. return;
  246. }
  247. if (lpszA == NULL)
  248. return;
  249. if( PRIMARYLANGID(lcid) == LANG_JAPANESE ) {
  250. while( length ) {
  251. if( IsDBCSLeadByte(*lpszA) && (length >= 2) ) {
  252. // Adding length>=2 ensure the Lead Byte is followed by
  253. // a trail byte , Fix bug #102729
  254. //
  255. // This is a DBCS character, check trailbyte is 0x5C or not.
  256. //
  257. lpszA++;
  258. length--;
  259. if( *lpszA == 0x13 ) {
  260. *lpszA = (UCHAR)0x5C;
  261. }
  262. }
  263. switch( (UCHAR) *lpszA ) {
  264. case 0x10 :
  265. *lpszA = (UCHAR)0xBF;
  266. break;
  267. case 0x11 :
  268. *lpszA = (UCHAR)0xAE;
  269. break;
  270. case 0x12 :
  271. *lpszA = (UCHAR)0xAA;
  272. break;
  273. }
  274. //
  275. // next char
  276. //
  277. lpszA++;
  278. length--;
  279. }
  280. }
  281. else if (PRIMARYLANGID(lcid) == LANG_CHINESE ||
  282. PRIMARYLANGID(lcid) == LANG_KOREAN) {
  283. while( length ) {
  284. switch( (UCHAR) *lpszA ) {
  285. case 0x10 :
  286. *lpszA = (UCHAR)0xBF;
  287. break;
  288. case 0x11 :
  289. *lpszA = (UCHAR)0xAE;
  290. break;
  291. case 0x12 :
  292. *lpszA = (UCHAR)0xAA;
  293. break;
  294. }
  295. // have to check after restoring leadbyte values
  296. if( IsDBCSLeadByte(*lpszA) && *(lpszA+1) == 0x13 ) {
  297. *(lpszA+1) = (UCHAR)0x5C;
  298. }
  299. //
  300. // next char
  301. //
  302. lpszA++;
  303. length--;
  304. }
  305. }
  306. }
  307. DWORD
  308. szToWide(
  309. LPWSTR lpszW,
  310. LPCSTR lpszC,
  311. INT nSize
  312. )
  313. {
  314. if (!MultiByteToWideChar(CP_ACP,
  315. MB_PRECOMPOSED,
  316. lpszC,
  317. -1,
  318. lpszW,
  319. nSize))
  320. {
  321. return (GetLastError()) ;
  322. }
  323. return NO_ERROR ;
  324. }
  325. NWCCODE
  326. MapNtStatus(
  327. const NTSTATUS ntstatus,
  328. const NCP_CLASS ncpclass
  329. )
  330. {
  331. LPNTSTATUS_TO_NCP pErrorMap ;
  332. if (ntstatus == STATUS_SUCCESS)
  333. return SUCCESSFUL ;
  334. switch ( ncpclass ) {
  335. case NcpClassBindery:
  336. pErrorMap = MapNcpBinderyErrors ;
  337. break ;
  338. case NcpClassDir:
  339. pErrorMap = MapNcpDirErrors ;
  340. break ;
  341. case NcpClassConnect:
  342. pErrorMap = MapNcpConnectErrors ;
  343. break ;
  344. default:
  345. return 0xFFFF ;
  346. }
  347. while (pErrorMap->NtStatus)
  348. {
  349. if (pErrorMap->NtStatus == ntstatus)
  350. return (pErrorMap->NcpCode) ;
  351. pErrorMap++ ;
  352. }
  353. return 0xFFFF ;
  354. }
  355. DWORD
  356. SetWin32ErrorFromNtStatus(
  357. NTSTATUS NtStatus
  358. )
  359. {
  360. DWORD Status ;
  361. if (NtStatus & 0xC0010000) { // netware specific
  362. Status = ERROR_EXTENDED_ERROR ;
  363. } else if (NtStatus == NWRDR_PASSWORD_HAS_EXPIRED) {
  364. Status = 0 ; // note this is not an error (the operation suceeded!)
  365. } else {
  366. Status = RtlNtStatusToDosError(NtStatus) ;
  367. }
  368. SetLastError(Status) ;
  369. return Status ;
  370. }
  371. //
  372. // FormatString - Supplies an ANSI string which describes how to
  373. // convert from the input arguments into NCP request fields, and
  374. // from the NCP response fields into the output arguments.
  375. //
  376. // Field types, request/response:
  377. //
  378. // 'b' byte ( byte / byte* )
  379. // 'w' hi-lo word ( word / word* )
  380. // 'd' hi-lo dword ( dword / dword* )
  381. // '-' zero/skip byte ( void )
  382. // '=' zero/skip word ( void )
  383. // ._. zero/skip string ( word )
  384. // 'p' pstring ( char* )
  385. // 'P' DBCS pstring ( char* )
  386. // 'c' cstring ( char* )
  387. // 'C' cstring followed skip word ( char*, word )
  388. // 'r' raw bytes ( byte*, word )
  389. // 'R' DBCS raw bytes ( byte*, word )
  390. // 'u' p unicode string ( UNICODE_STRING * )
  391. // 'U' p uppercase string( UNICODE_STRING * )
  392. // 'W' word n followed by an array of word[n] ( word, word* )
  393. //
  394. //
  395. //
  396. //
  397. // Standard NCP Function Block
  398. //
  399. //
  400. // NWCCODE NWAPI DLLEXPORT
  401. // NW***(
  402. // NWCONN_HANDLE hConn,
  403. // )
  404. // {
  405. // NWCCODE NcpCode;
  406. // NTSTATUS NtStatus;
  407. //
  408. // NtStatus = NwlibMakeNcp(
  409. // hConn, // Connection Handle
  410. // FSCTL_NWR_NCP_E3H, // Bindery function
  411. // , // Max request packet size
  412. // , // Max response packet size
  413. // "b|", // Format string
  414. // // === REQUEST ================================
  415. // 0x, // b Function
  416. // // === REPLY ==================================
  417. // );
  418. //
  419. // return MapNtStatus( NtStatus, NcpClassXXX );
  420. // }
  421. //
  422. //
  423. NWCCODE NWAPI DLLEXPORT
  424. NWAddTrusteeToDirectory(
  425. NWCONN_HANDLE hConn,
  426. NWDIR_HANDLE dirHandle,
  427. const char NWFAR *pszPath,
  428. NWOBJ_ID dwTrusteeID,
  429. NWACCESS_RIGHTS rightsMask
  430. )
  431. {
  432. unsigned short reply;
  433. NTSTATUS NtStatus ;
  434. PNWC_SERVER_INFO pServerInfo = (PNWC_SERVER_INFO)hConn ;
  435. NtStatus = NwlibMakeNcp(
  436. pServerInfo->hConn, // Connection Handle
  437. FSCTL_NWR_NCP_E2H, // Directory function
  438. 265, // Max request packet size
  439. 2, // Max response packet size
  440. "bbrbP|", // Format string
  441. // === REQUEST ================================
  442. 0x0d, // b Add trustee to directory
  443. dirHandle, // b 0xffffffff to start or last returned ID when enumerating HI-LO
  444. &dwTrusteeID,DW_SIZE, // r Object ID to assigned to directory
  445. rightsMask, // b User rights for directory
  446. pszPath, // P Directory (if dirHandle = 0 then vol:directory)
  447. // === REPLY ==================================
  448. &reply // Not used
  449. );
  450. (void) SetWin32ErrorFromNtStatus( NtStatus );
  451. return MapNtStatus( NtStatus, NcpClassDir );
  452. }
  453. NWCCODE NWAPI DLLEXPORT
  454. NWAllocPermanentDirectoryHandle(
  455. NWCONN_HANDLE hConn,
  456. NWDIR_HANDLE dirHandle,
  457. char NWFAR *pszDirPath,
  458. NWDIR_HANDLE NWFAR *pbNewDirHandle,
  459. NWACCESS_RIGHTS NWFAR *pbRightsMask
  460. )
  461. {
  462. NTSTATUS NtStatus ;
  463. PNWC_SERVER_INFO pServerInfo = (PNWC_SERVER_INFO)hConn ;
  464. NtStatus = NwlibMakeNcp(
  465. pServerInfo->hConn, // Connection Handle
  466. FSCTL_NWR_NCP_E2H, // E2 Function function
  467. 261, // Max request packet size
  468. 4, // Max response packet size
  469. "bbbP|bb", // Format string
  470. // === REQUEST ================================
  471. 0x12, // b Function Alloc Perm Dir
  472. dirHandle, // b 0 for new
  473. 0, // b Drive Letter
  474. pszDirPath, // P Volume Name (SYS: or SYS:\PUBLIC)
  475. // === REPLY ==================================
  476. pbNewDirHandle, // b Dir Handle
  477. pbRightsMask // b Rights
  478. );
  479. (void) SetWin32ErrorFromNtStatus( NtStatus );
  480. return MapNtStatus( NtStatus, NcpClassDir );
  481. }
  482. NWCCODE NWAPI DLLEXPORT
  483. NWAllocTemporaryDirectoryHandle(
  484. NWCONN_HANDLE hConn,
  485. NWDIR_HANDLE dirHandle,
  486. char NWFAR *pszDirPath,
  487. NWDIR_HANDLE NWFAR *pbNewDirHandle,
  488. NWACCESS_RIGHTS NWFAR *pbRightsMask
  489. )
  490. {
  491. NTSTATUS NtStatus ;
  492. PNWC_SERVER_INFO pServerInfo = (PNWC_SERVER_INFO)hConn ;
  493. NtStatus = NwlibMakeNcp(
  494. pServerInfo->hConn, // Connection Handle
  495. FSCTL_NWR_NCP_E2H, // E2 Function function
  496. 261, // Max request packet size
  497. 4, // Max response packet size
  498. "bbbP|bb", // Format string
  499. // === REQUEST ================================
  500. 0x13, // b Function Alloc Temp Dir
  501. dirHandle, // b 0 for new
  502. 0, // b Drive Letter
  503. pszDirPath, // P Volume Name (SYS: or SYS:\PUBLIC)
  504. // === REPLY ==================================
  505. pbNewDirHandle, // b Dir Handle
  506. pbRightsMask // b Rights
  507. );
  508. (void) SetWin32ErrorFromNtStatus( NtStatus );
  509. return MapNtStatus( NtStatus, NcpClassDir );
  510. }
  511. NWCCODE NWAPI DLLEXPORT
  512. NWCheckConsolePrivileges(
  513. NWCONN_HANDLE hConn
  514. )
  515. {
  516. WORD wDummy;
  517. NTSTATUS NtStatus ;
  518. PNWC_SERVER_INFO pServerInfo = (PNWC_SERVER_INFO)hConn ;
  519. NtStatus = NwlibMakeNcp(
  520. pServerInfo->hConn, // Connection Handle
  521. FSCTL_NWR_NCP_E3H, // Bindery function
  522. 3, // Max request packet size
  523. 2, // Max response packet size
  524. "b|r", // Format string
  525. // === REQUEST ================================
  526. 0xC8, // b Get Console Privilges
  527. // === REPLY ==================================
  528. &wDummy,W_SIZE // r Dummy Response
  529. );
  530. (void) SetWin32ErrorFromNtStatus( NtStatus );
  531. return MapNtStatus( NtStatus, NcpClassBindery );
  532. }
  533. NWCCODE NWAPI DLLEXPORT
  534. NWDeallocateDirectoryHandle(
  535. NWCONN_HANDLE hConn,
  536. NWDIR_HANDLE dirHandle
  537. )
  538. {
  539. WORD wDummy;
  540. NTSTATUS NtStatus ;
  541. PNWC_SERVER_INFO pServerInfo = (PNWC_SERVER_INFO)hConn ;
  542. NtStatus = NwlibMakeNcp(
  543. pServerInfo->hConn, // Connection Handle
  544. FSCTL_NWR_NCP_E2H, // E2 Function function
  545. 4, // Max request packet size
  546. 2, // Max response packet size
  547. "bb|w", // Format string
  548. // === REQUEST ================================
  549. 0x14, // b Function Dealloc Dir Hand
  550. dirHandle, // b 0 for new
  551. // === REPLY ==================================
  552. &wDummy
  553. );
  554. (void) SetWin32ErrorFromNtStatus( NtStatus );
  555. return MapNtStatus( NtStatus, NcpClassDir );
  556. }
  557. NWCCODE NWAPI DLLEXPORT
  558. NWGetFileServerVersionInfo(
  559. NWCONN_HANDLE hConn,
  560. VERSION_INFO NWFAR *lpVerInfo
  561. )
  562. {
  563. NTSTATUS NtStatus ;
  564. PNWC_SERVER_INFO pServerInfo = (PNWC_SERVER_INFO)hConn ;
  565. NtStatus = NwlibMakeNcp(
  566. pServerInfo->hConn, // Connection Handle
  567. FSCTL_NWR_NCP_E3H, // Bindery function
  568. 3, // Max request packet size
  569. 130, // Max response packet size
  570. "b|r", // Format string
  571. // === REQUEST ================================
  572. 0x11, // b Get File Server Information
  573. // === REPLY ==================================
  574. lpVerInfo, // r File Version Structure
  575. sizeof(VERSION_INFO)
  576. );
  577. // Convert HI-LO words to LO-HI
  578. // ===========================================================
  579. lpVerInfo->ConnsSupported = wSWAP( lpVerInfo->ConnsSupported );
  580. lpVerInfo->connsInUse = wSWAP( lpVerInfo->connsInUse );
  581. lpVerInfo->maxVolumes = wSWAP( lpVerInfo->maxVolumes );
  582. lpVerInfo->PeakConns = wSWAP( lpVerInfo->PeakConns );
  583. (void) SetWin32ErrorFromNtStatus( NtStatus );
  584. return MapNtStatus( NtStatus, NcpClassBindery );
  585. }
  586. NWCCODE NWAPI DLLEXPORT
  587. NWGetInternetAddress(
  588. NWCONN_HANDLE hConn,
  589. NWCONN_NUM nConnNum,
  590. NWNET_ADDR NWFAR *pIntAddr
  591. )
  592. {
  593. NTSTATUS NtStatus ;
  594. PNWC_SERVER_INFO pServerInfo = (PNWC_SERVER_INFO)hConn ;
  595. NtStatus = NwlibMakeNcp(
  596. pServerInfo->hConn, // Connection Handle
  597. FSCTL_NWR_NCP_E3H, // Bindery function
  598. 4, // Max request packet size
  599. 14, // Max response packet size
  600. "bb|r", // Format string
  601. // === REQUEST ================================
  602. 0x13, // b Get Internet Address
  603. nConnNum, // b Connection Number
  604. // === REPLY ==================================
  605. pIntAddr,12 // r File Version Structure
  606. );
  607. (void) SetWin32ErrorFromNtStatus( NtStatus );
  608. return MapNtStatus( NtStatus, NcpClassBindery );
  609. }
  610. NWCCODE NWAPI DLLEXPORT
  611. NWGetObjectName(
  612. NWCONN_HANDLE hConn,
  613. NWOBJ_ID dwObjectID,
  614. char NWFAR *pszObjName,
  615. NWOBJ_TYPE NWFAR *pwObjType )
  616. {
  617. NWOBJ_ID dwRetID;
  618. NTSTATUS NtStatus ;
  619. PNWC_SERVER_INFO pServerInfo = (PNWC_SERVER_INFO)hConn ;
  620. NtStatus = NwlibMakeNcp(
  621. pServerInfo->hConn, // Connection Handle
  622. FSCTL_NWR_NCP_E3H, // Bindery function
  623. 7, // Max request packet size
  624. 56, // Max response packet size
  625. "br|rrR", // Format string
  626. // === REQUEST ================================
  627. 0x36, // b Get Bindery Object Name
  628. &dwObjectID,DW_SIZE, // r Object ID HI-LO
  629. // === REPLY ==================================
  630. &dwRetID,DW_SIZE, // r Object ID HI-LO
  631. pwObjType,W_SIZE, // r Object Type
  632. pszObjName,48 // R Object Name
  633. );
  634. (void) SetWin32ErrorFromNtStatus( NtStatus );
  635. return MapNtStatus( NtStatus, NcpClassBindery );
  636. }
  637. // This function not supported (E3 E9)
  638. NWCCODE NWAPI DLLEXPORT
  639. NWGetVolumeInfoWithNumber(
  640. NWCONN_HANDLE hConn,
  641. NWVOL_NUM nVolNum,
  642. char NWFAR *pszVolName,
  643. NWNUMBER NWFAR *pwTotalBlocks,
  644. NWNUMBER NWFAR *pwSectors,
  645. NWNUMBER NWFAR *pwAvailBlocks,
  646. NWNUMBER NWFAR *pwTotalDir,
  647. NWNUMBER NWFAR *pwAvailDir,
  648. NWVOL_FLAGS NWFAR *pfVolRemovable
  649. )
  650. {
  651. WORD wTime; // w Elapsed Time
  652. BYTE bVoln; // b Vol Num
  653. BYTE bDriven; // b Drive Num
  654. WORD wStartBlock; // w Starting Block
  655. WORD wMaxUsedDir; // w Actual Max Used Directory Entries
  656. BYTE bVolHashed; // b Volume is hashed
  657. BYTE bVolCached; // b Volume is Cached
  658. BYTE bVolMounted; // b Volume is mounted
  659. NTSTATUS NtStatus ;
  660. PNWC_SERVER_INFO pServerInfo = (PNWC_SERVER_INFO)hConn ;
  661. NtStatus = NwlibMakeNcp(
  662. pServerInfo->hConn, // Connection Handle
  663. FSCTL_NWR_NCP_E3H, // Bindery function
  664. 4, // Max request packet size
  665. 42, // Max response packet size
  666. "bb|wbbwwwwwwwbbbbr", // Format string
  667. // === REQUEST ================================
  668. 0xe9, // b Get Volume Information
  669. nVolNum, // b Volume Number (0 to Max Vol)
  670. // === REPLY ==================================
  671. &wTime, // w Elapsed Time
  672. &bVoln, // b Vol Num
  673. &bDriven, // b Drive Num
  674. pwSectors, // w Sectors per block
  675. &wStartBlock, // w Starting Block
  676. pwTotalBlocks, // w Total Blocks
  677. pwAvailBlocks, // w Available Blocks (free)
  678. pwTotalDir, // w Total Dir Slots
  679. pwAvailDir, // w Available Directory Slots
  680. &wMaxUsedDir, // w Actual Max Used Directory Entries
  681. &bVolHashed, // b Volume is hashed
  682. &bVolCached, // b Volume is Cached
  683. pfVolRemovable, // b Volume is removable
  684. &bVolMounted, // b Volume is mounted
  685. pszVolName,16 // r Volume Name
  686. );
  687. (void) SetWin32ErrorFromNtStatus( NtStatus );
  688. return MapNtStatus( NtStatus, NcpClassBindery );
  689. }
  690. NWCCODE NWAPI DLLEXPORT
  691. NWGetVolumeInfoWithHandle(
  692. NWCONN_HANDLE hConn,
  693. NWDIR_HANDLE nDirHand,
  694. char NWFAR *pszVolName,
  695. NWNUMBER NWFAR *pwTotalBlocks,
  696. NWNUMBER NWFAR *pwSectors,
  697. NWNUMBER NWFAR *pwAvailBlocks,
  698. NWNUMBER NWFAR *pwTotalDir,
  699. NWNUMBER NWFAR *pwAvailDir,
  700. NWVOL_FLAGS NWFAR *pfVolRemovable
  701. )
  702. {
  703. NTSTATUS NtStatus ;
  704. PNWC_SERVER_INFO pServerInfo = (PNWC_SERVER_INFO)hConn ;
  705. NtStatus = NwlibMakeNcp(
  706. pServerInfo->hConn, // Connection Handle
  707. FSCTL_NWR_NCP_E2H, // Bindery function
  708. 4, // Max request packet size
  709. 30, // Max response packet size
  710. "bb|wwwwwrb", // Format string
  711. // === REQUEST ================================
  712. 0x15, // b Get Volume Information
  713. nDirHand, // b Dir Handle
  714. // === REPLY ==================================
  715. pwSectors, // w Sectors per block
  716. pwTotalBlocks, // w Total Blocks
  717. pwAvailBlocks, // w Available Blocks (free)
  718. pwTotalDir, // w Total Dir Slots
  719. pwAvailDir, // w Available Directory Slots
  720. pszVolName,16, // r Volume Name
  721. pfVolRemovable // b Volume is removable
  722. );
  723. (void) SetWin32ErrorFromNtStatus( NtStatus );
  724. return MapNtStatus( NtStatus, NcpClassDir );
  725. }
  726. NWCCODE NWAPI DLLEXPORT
  727. NWGetVolumeName(
  728. NWCONN_HANDLE hConn,
  729. NWVOL_NUM bVolNum,
  730. char NWFAR *pszVolName
  731. )
  732. {
  733. NTSTATUS NtStatus ;
  734. PNWC_SERVER_INFO pServerInfo = (PNWC_SERVER_INFO)hConn ;
  735. NtStatus = NwlibMakeNcp(
  736. pServerInfo->hConn, // Connection Handle
  737. FSCTL_NWR_NCP_E2H, // Directory Services
  738. 4, // Max request packet size
  739. 19, // Max response packet size
  740. "bb|p", // Format string
  741. // === REQUEST ================================
  742. 0x06, // Get Volume Name
  743. bVolNum, // Volume Number
  744. // === REPLY ==================================
  745. pszVolName // Return Volume name
  746. );
  747. (void) SetWin32ErrorFromNtStatus( NtStatus );
  748. return MapNtStatus( NtStatus, NcpClassDir );
  749. }
  750. NWCCODE NWAPI DLLEXPORT
  751. NWIsObjectInSet(
  752. NWCONN_HANDLE hConn,
  753. const char NWFAR *lpszObjectName,
  754. NWOBJ_TYPE wObjType,
  755. const char NWFAR *lpszPropertyName,
  756. const char NWFAR *lpszMemberName,
  757. NWOBJ_TYPE wMemberType
  758. )
  759. {
  760. NTSTATUS NtStatus ;
  761. PNWC_SERVER_INFO pServerInfo = (PNWC_SERVER_INFO)hConn ;
  762. WORD Dummy;
  763. NtStatus = NwlibMakeNcp(
  764. pServerInfo->hConn, // Connection Handle
  765. FSCTL_NWR_NCP_E3H, // Bindery function
  766. 122, // Max request packet size
  767. 2, // Max response packet size
  768. "brPPrP|", // Format string
  769. // === REQUEST ================================
  770. 0x43, // b Read Property Value
  771. &wObjType,W_SIZE, // r OT_??? HI-LO
  772. lpszObjectName, // P Object Name
  773. lpszPropertyName, // P Prop Name
  774. &wMemberType,W_SIZE, // r Member Type
  775. lpszMemberName, // P Member Name
  776. // === REPLY ==================================
  777. &Dummy,W_SIZE
  778. );
  779. (void) SetWin32ErrorFromNtStatus( NtStatus );
  780. return MapNtStatus( NtStatus, NcpClassBindery );
  781. } // NWIsObjectInSet
  782. NWCCODE NWAPI DLLEXPORT
  783. NWLoginToFileServer(
  784. NWCONN_HANDLE hConn,
  785. const char NWFAR *pszUserName,
  786. NWOBJ_TYPE wObType,
  787. const char NWFAR *pszPassword
  788. )
  789. {
  790. NETRESOURCEW NetResource;
  791. DWORD dwRes, dwSize;
  792. NWCCODE nwRes;
  793. LPWSTR pszUserNameW = NULL,
  794. pszPasswordW = NULL;
  795. PNWC_SERVER_INFO pServerInfo = (PNWC_SERVER_INFO)hConn ;
  796. //
  797. // validate parameters
  798. //
  799. if (!hConn || !pszUserName || !pszPassword)
  800. return INVALID_CONNECTION ;
  801. //
  802. // allocate memory for unicode strings and convert ANSI input
  803. // to Unicode.
  804. //
  805. dwSize = strlen(pszUserName)+1 ;
  806. if (!(pszUserNameW = (LPWSTR)LocalAlloc(
  807. LPTR,
  808. dwSize * sizeof(WCHAR))))
  809. {
  810. nwRes = REQUESTER_ERROR ;
  811. goto ExitPoint ;
  812. }
  813. if (szToWide( pszUserNameW, pszUserName, dwSize ) != NO_ERROR)
  814. {
  815. nwRes = REQUESTER_ERROR ;
  816. goto ExitPoint ;
  817. }
  818. dwSize = strlen(pszPassword)+1 ;
  819. if (!(pszPasswordW = (LPWSTR)LocalAlloc(
  820. LPTR,
  821. dwSize * sizeof(WCHAR))))
  822. {
  823. nwRes = REQUESTER_ERROR ;
  824. goto ExitPoint ;
  825. }
  826. if (szToWide( pszPasswordW, pszPassword, dwSize ) != NO_ERROR)
  827. {
  828. nwRes = REQUESTER_ERROR ;
  829. goto ExitPoint ;
  830. }
  831. NetResource.dwScope = 0 ;
  832. NetResource.dwUsage = 0 ;
  833. NetResource.dwType = RESOURCETYPE_ANY;
  834. NetResource.lpLocalName = NULL;
  835. NetResource.lpRemoteName = (LPWSTR) pServerInfo->ServerString.Buffer;
  836. NetResource.lpComment = NULL;
  837. NetResource.lpProvider = NULL ;
  838. //
  839. // make the connection
  840. //
  841. dwRes=NPAddConnection ( &NetResource,
  842. pszPasswordW,
  843. pszUserNameW );
  844. if( NO_ERROR != dwRes ) {
  845. dwRes = GetLastError();
  846. switch( dwRes ) {
  847. case ERROR_SESSION_CREDENTIAL_CONFLICT:
  848. nwRes = SUCCESSFUL;
  849. break;
  850. case ERROR_ALREADY_ASSIGNED:
  851. nwRes = ALREADY_ATTACHED;
  852. break;
  853. case ERROR_ACCESS_DENIED:
  854. case ERROR_BAD_DEV_TYPE:
  855. case ERROR_BAD_DEVICE:
  856. case ERROR_BAD_NET_NAME:
  857. case ERROR_BAD_PROFILE:
  858. case ERROR_CANNOT_OPEN_PROFILE:
  859. case ERROR_DEVICE_ALREADY_REMEMBERED:
  860. case ERROR_EXTENDED_ERROR:
  861. case ERROR_INVALID_PASSWORD:
  862. case ERROR_NO_NET_OR_BAD_PATH:
  863. case ERROR_NO_NETWORK:
  864. nwRes = INVALID_CONNECTION;
  865. break;
  866. default:
  867. nwRes = INVALID_CONNECTION;
  868. break;
  869. }
  870. } else {
  871. nwRes = SUCCESSFUL;
  872. }
  873. ExitPoint:
  874. if (pszUserNameW)
  875. (void) LocalFree((HLOCAL) pszUserNameW) ;
  876. if (pszPasswordW)
  877. (void) LocalFree((HLOCAL) pszPasswordW) ;
  878. return( nwRes );
  879. }
  880. NWCCODE NWAPI DLLEXPORT
  881. NWLogoutFromFileServer(
  882. NWCONN_HANDLE hConn
  883. )
  884. {
  885. DWORD dwRes;
  886. NWCCODE nwRes;
  887. PNWC_SERVER_INFO pServerInfo = (PNWC_SERVER_INFO)hConn ;
  888. //
  889. // cancel all explicit connections to that server
  890. //
  891. (void) CancelAllConnections ( pServerInfo->ServerString.Buffer );
  892. //
  893. // now cancel the any connection to \\servername.
  894. //
  895. dwRes=NPCancelConnection( pServerInfo->ServerString.Buffer, TRUE );
  896. if( NO_ERROR != dwRes ) {
  897. dwRes = GetLastError();
  898. switch( dwRes )
  899. {
  900. case ERROR_NOT_CONNECTED:
  901. case ERROR_INVALID_HANDLE:
  902. nwRes = SUCCESSFUL;
  903. break;
  904. case ERROR_BAD_PROFILE:
  905. case ERROR_CANNOT_OPEN_PROFILE:
  906. case ERROR_DEVICE_IN_USE:
  907. case ERROR_EXTENDED_ERROR:
  908. nwRes = INVALID_CONNECTION;
  909. break;
  910. default:
  911. nwRes = INVALID_CONNECTION;
  912. break;
  913. }
  914. } else {
  915. nwRes = SUCCESSFUL;
  916. }
  917. return( nwRes );
  918. }
  919. NWCCODE NWAPI DLLEXPORT
  920. NWReadPropertyValue(
  921. NWCONN_HANDLE hConn,
  922. const char NWFAR *pszObjName,
  923. NWOBJ_TYPE wObjType,
  924. char NWFAR *pszPropName,
  925. unsigned char ucSegment,
  926. char NWFAR *pValue,
  927. NWFLAGS NWFAR *pucMoreFlag,
  928. NWFLAGS NWFAR *pucPropFlag
  929. )
  930. {
  931. NTSTATUS NtStatus ;
  932. PNWC_SERVER_INFO pServerInfo = (PNWC_SERVER_INFO)hConn ;
  933. NtStatus = NwlibMakeNcp(
  934. pServerInfo->hConn, // Connection Handle
  935. FSCTL_NWR_NCP_E3H, // Bindery function
  936. 70, // Max request packet size
  937. 132, // Max response packet size
  938. "brPbP|rbb", // Format string
  939. // === REQUEST ================================
  940. 0x3D, // b Read Property Value
  941. &wObjType,W_SIZE, // r Object Type HI-LO
  942. pszObjName, // P Object Name
  943. ucSegment, // b Segment Number
  944. pszPropName, // P Property Name
  945. // === REPLY ==================================
  946. pValue,128, // r Property value
  947. pucMoreFlag, // b More Flag
  948. pucPropFlag // b Prop Flag
  949. );
  950. (void) SetWin32ErrorFromNtStatus( NtStatus );
  951. return MapNtStatus( NtStatus, NcpClassBindery );
  952. }
  953. NWCCODE NWAPI DLLEXPORT
  954. NWScanObject(
  955. NWCONN_HANDLE hConn,
  956. const char NWFAR *pszSearchName,
  957. NWOBJ_TYPE wObjSearchType,
  958. NWOBJ_ID NWFAR *pdwObjectID,
  959. char NWFAR *pszObjectName,
  960. NWOBJ_TYPE NWFAR *pwObjType,
  961. NWFLAGS NWFAR *pucHasProperties,
  962. NWFLAGS NWFAR *pucObjectFlags,
  963. NWFLAGS NWFAR *pucObjSecurity
  964. )
  965. {
  966. NTSTATUS NtStatus ;
  967. PNWC_SERVER_INFO pServerInfo = (PNWC_SERVER_INFO)hConn ;
  968. NtStatus = NwlibMakeNcp(
  969. pServerInfo->hConn, // Connection Handle
  970. FSCTL_NWR_NCP_E3H, // Bindery function
  971. 57, // Max request packet size
  972. 59, // Max response packet size
  973. "brrP|rrRbbb", // Format string
  974. // === REQUEST ================================
  975. 0x37, // b Scan bindery object
  976. pdwObjectID,DW_SIZE, // r 0xffffffff to start or last returned ID when enumerating HI-LO
  977. &wObjSearchType,W_SIZE, // r Use OT_??? Defines HI-LO
  978. pszSearchName, // P Search Name. (use "*") for all
  979. // === REPLY ==================================
  980. pdwObjectID,DW_SIZE, // r Returned ID HI-LO
  981. pwObjType,W_SIZE, // r rObject Type HI-LO
  982. pszObjectName,48, // R Found Name
  983. pucObjectFlags, // b Object Flag
  984. pucObjSecurity, // b Object Security
  985. pucHasProperties // b Has Properties
  986. );
  987. (void) SetWin32ErrorFromNtStatus( NtStatus );
  988. return MapNtStatus( NtStatus, NcpClassBindery );
  989. }
  990. NWCCODE NWAPI DLLEXPORT
  991. NWScanProperty(
  992. NWCONN_HANDLE hConn,
  993. const char NWFAR *pszObjectName,
  994. NWOBJ_TYPE wObjType,
  995. char NWFAR *pszSearchName,
  996. NWOBJ_ID NWFAR *pdwSequence,
  997. char NWFAR *pszPropName,
  998. NWFLAGS NWFAR *pucPropFlags,
  999. NWFLAGS NWFAR *pucPropSecurity,
  1000. NWFLAGS NWFAR *pucHasValue,
  1001. NWFLAGS NWFAR *pucMore
  1002. )
  1003. {
  1004. NTSTATUS NtStatus ;
  1005. PNWC_SERVER_INFO pServerInfo = (PNWC_SERVER_INFO)hConn ;
  1006. NtStatus = NwlibMakeNcp(
  1007. pServerInfo->hConn, // Connection Handle
  1008. FSCTL_NWR_NCP_E3H, // Bindery function
  1009. 73, // Max request packet size
  1010. 26, // Max response packet size
  1011. "brPrP|Rbbrbb", // Format string
  1012. // === REQUEST ================================
  1013. 0x3C, // b Scan Prop function
  1014. &wObjType,W_SIZE, // r Type of Object
  1015. pszObjectName, // P Object Name
  1016. pdwSequence,DW_SIZE, // r Sequence HI-LO
  1017. pszSearchName, // P Property Name to Search for
  1018. // === REPLY ==================================
  1019. pszPropName,16, // R Returned Property Name
  1020. pucPropFlags, // b Property Flags
  1021. pucPropSecurity, // b Property Security
  1022. pdwSequence,DW_SIZE, // r Sequence HI-LO
  1023. pucHasValue, // b Property Has value
  1024. pucMore // b More Properties
  1025. );
  1026. (void) SetWin32ErrorFromNtStatus( NtStatus );
  1027. return MapNtStatus( NtStatus, NcpClassBindery );
  1028. }
  1029. NWCCODE NWAPI DLLEXPORT
  1030. NWGetFileServerDateAndTime(
  1031. NWCONN_HANDLE hConn,
  1032. BYTE NWFAR *year,
  1033. BYTE NWFAR *month,
  1034. BYTE NWFAR *day,
  1035. BYTE NWFAR *hour,
  1036. BYTE NWFAR *minute,
  1037. BYTE NWFAR *second,
  1038. BYTE NWFAR *dayofweek
  1039. )
  1040. {
  1041. NTSTATUS NtStatus ;
  1042. PNWC_SERVER_INFO pServerInfo = (PNWC_SERVER_INFO)hConn ;
  1043. NtStatus = NwlibMakeNcp(
  1044. pServerInfo->hConn, // Connection Handle
  1045. FSCTL_NWR_NCP_E0H, // Server function
  1046. 0, // Max request packet size
  1047. 9, // Max response packet size
  1048. "|bbbbbbb", // Format string
  1049. // === REQUEST ================================
  1050. // === REPLY ==================================
  1051. year,
  1052. month,
  1053. day,
  1054. hour,
  1055. minute,
  1056. second,
  1057. dayofweek
  1058. );
  1059. (void) SetWin32ErrorFromNtStatus( NtStatus );
  1060. return MapNtStatus( NtStatus, NcpClassConnect );
  1061. } // NWGetFileServerDateAndTime
  1062. //
  1063. // worker routines
  1064. //
  1065. #define NW_RDR_SERVER_PREFIX L"\\Device\\Nwrdr\\"
  1066. DWORD
  1067. CancelAllConnections(
  1068. LPWSTR pszServer
  1069. )
  1070. /*++
  1071. Routine Description:
  1072. This routine cancels all connections to a server
  1073. Arguments:
  1074. pszServer - the server we are disconnecting from
  1075. Return Value:
  1076. NO_ERROR or win32 error for failure.
  1077. --*/
  1078. {
  1079. DWORD status = ERROR_NO_NETWORK;
  1080. HANDLE EnumHandle = (HANDLE) NULL;
  1081. LPNETRESOURCE NetR = NULL;
  1082. DWORD BytesNeeded = 4096;
  1083. DWORD EntriesRead;
  1084. DWORD i;
  1085. //
  1086. // Retrieve the list of connections
  1087. //
  1088. status = NPOpenEnum(
  1089. RESOURCE_CONNECTED,
  1090. 0,
  1091. 0,
  1092. NULL,
  1093. &EnumHandle
  1094. );
  1095. if (status != NO_ERROR) {
  1096. EnumHandle = (HANDLE) NULL;
  1097. goto CleanExit;
  1098. }
  1099. //
  1100. // Allocate buffer to get connection list.
  1101. //
  1102. if ((NetR = (LPNETRESOURCE) LocalAlloc(
  1103. LPTR,
  1104. (UINT) BytesNeeded
  1105. )) == NULL) {
  1106. status = ERROR_NOT_ENOUGH_MEMORY;
  1107. goto CleanExit;
  1108. }
  1109. do {
  1110. EntriesRead = 0xFFFFFFFF; // Read as many as possible
  1111. status = NPEnumResource(
  1112. EnumHandle,
  1113. &EntriesRead,
  1114. (LPVOID) NetR,
  1115. &BytesNeeded
  1116. );
  1117. if (status == WN_SUCCESS)
  1118. {
  1119. LPNETRESOURCE TmpPtr = NetR;
  1120. for (i = 0; i < EntriesRead; i++, TmpPtr++)
  1121. {
  1122. LPWSTR pszTmp ;
  1123. //
  1124. // If it contains the server we are logging off from, we want
  1125. // to cancel it. First, lets extract the server name part.
  1126. //
  1127. pszTmp = TmpPtr->lpRemoteName ;
  1128. if (!pszTmp || !*pszTmp)
  1129. continue ;
  1130. if ((*pszTmp == L'\\') && (*(pszTmp+1) == L'\\'))
  1131. pszTmp += 2 ;
  1132. if (pszTmp = wcschr(pszTmp, L'\\'))
  1133. *pszTmp = 0 ;
  1134. if (_wcsicmp(TmpPtr->lpRemoteName, pszServer) == 0)
  1135. {
  1136. //
  1137. // Aha, it matches. Restore the '\' and nuke it with force.
  1138. // Ignore errors here.
  1139. //
  1140. if (pszTmp)
  1141. *pszTmp = L'\\' ;
  1142. if (TmpPtr->lpLocalName && *(TmpPtr->lpLocalName))
  1143. {
  1144. //
  1145. // if local name present, its a redirection.
  1146. //
  1147. (void) NPCancelConnection( TmpPtr->lpLocalName,TRUE );
  1148. }
  1149. else
  1150. {
  1151. //
  1152. // else cancel the deviceless use
  1153. //
  1154. (void) NPCancelConnection( TmpPtr->lpRemoteName,TRUE );
  1155. }
  1156. }
  1157. }
  1158. }
  1159. else if (status != WN_NO_MORE_ENTRIES) {
  1160. status = GetLastError();
  1161. if (status == WN_MORE_DATA) {
  1162. //
  1163. // Original buffer was too small. Free it and allocate
  1164. // the recommended size and then some to get as many
  1165. // entries as possible.
  1166. //
  1167. (void) LocalFree((HLOCAL) NetR);
  1168. if ((NetR = (LPNETRESOURCE) LocalAlloc(
  1169. LPTR,
  1170. (UINT) BytesNeeded
  1171. )) == NULL) {
  1172. status = ERROR_NOT_ENOUGH_MEMORY;
  1173. goto CleanExit;
  1174. }
  1175. }
  1176. else
  1177. {
  1178. //
  1179. // cant handle other errors. bag out.
  1180. //
  1181. goto CleanExit;
  1182. }
  1183. }
  1184. } while (status != WN_NO_MORE_ENTRIES);
  1185. if (status == WN_NO_MORE_ENTRIES)
  1186. {
  1187. status = NO_ERROR;
  1188. }
  1189. CleanExit:
  1190. if (EnumHandle != (HANDLE) NULL)
  1191. {
  1192. (void) NPCloseEnum(EnumHandle);
  1193. }
  1194. if (NetR != NULL)
  1195. {
  1196. (void) LocalFree((HLOCAL) NetR);
  1197. }
  1198. return status;
  1199. }
  1200. NWCCODE NWAPI DLLEXPORT
  1201. NWCreateQueue(
  1202. NWCONN_HANDLE hConn,
  1203. NWDIR_HANDLE dirHandle,
  1204. const char NWFAR *pszQueueName,
  1205. NWOBJ_TYPE wQueueType,
  1206. const char NWFAR *pszPathName,
  1207. NWOBJ_ID NWFAR *pdwQueueId
  1208. )
  1209. {
  1210. NTSTATUS NtStatus;
  1211. PNWC_SERVER_INFO pServerInfo = (PNWC_SERVER_INFO)hConn ;
  1212. NtStatus = NwlibMakeNcp(
  1213. pServerInfo->hConn, // Connection Handle
  1214. FSCTL_NWR_NCP_E3H, // Bindery function
  1215. 174, // Max request packet size
  1216. 6, // Max response packet size
  1217. "brPbP|r", // Format string
  1218. // === REQUEST ================================
  1219. 0x64, // b Create Queue
  1220. &wQueueType,W_SIZE, // r Queue Type HI-LO
  1221. pszQueueName, // P Queue Name
  1222. dirHandle, // b Directory Handle
  1223. pszPathName, // P Path name
  1224. // === REPLY ==================================
  1225. pdwQueueId,DW_SIZE // r Queue ID HI-LO
  1226. );
  1227. (void) SetWin32ErrorFromNtStatus(NtStatus);
  1228. return MapNtStatus( NtStatus, NcpClassBindery );
  1229. }
  1230. NWCCODE NWAPI DLLEXPORT
  1231. NWChangePropertySecurity(
  1232. NWCONN_HANDLE hConn,
  1233. const char NWFAR *pszObjName,
  1234. NWOBJ_TYPE wObjType,
  1235. const char NWFAR *pszPropertyName,
  1236. NWFLAGS ucObjSecurity
  1237. )
  1238. {
  1239. NTSTATUS NtStatus;
  1240. PNWC_SERVER_INFO pServerInfo = (PNWC_SERVER_INFO)hConn ;
  1241. NtStatus = NwlibMakeNcp (
  1242. pServerInfo->hConn, // Connection Handle
  1243. FSCTL_NWR_NCP_E3H, // Bindery function
  1244. 70, // Max request packet size
  1245. 2, // Max response packet size
  1246. "brPbP|", // Format string
  1247. // === REQUEST ================================
  1248. 0x3B, // b Change Property Security
  1249. &wObjType,W_SIZE, // r OT_??? HI-LO
  1250. pszObjName, // P Prop Name
  1251. ucObjSecurity, // b New Property security
  1252. pszPropertyName // P Property Name
  1253. // === REPLY ==================================
  1254. );
  1255. (void) SetWin32ErrorFromNtStatus( NtStatus );
  1256. return MapNtStatus( NtStatus, NcpClassBindery );
  1257. }
  1258. NWCCODE NWAPI DLLEXPORT
  1259. NWDestroyQueue(
  1260. NWCONN_HANDLE hConn,
  1261. NWOBJ_ID dwQueueId
  1262. )
  1263. {
  1264. NTSTATUS NtStatus;
  1265. PNWC_SERVER_INFO pServerInfo = (PNWC_SERVER_INFO)hConn ;
  1266. NtStatus = NwlibMakeNcp(
  1267. pServerInfo->hConn, // Connection Handle
  1268. FSCTL_NWR_NCP_E3H, // Bindery function
  1269. 7, // Max request packet size
  1270. 2, // Max response packet size
  1271. "bd|", // Format string
  1272. // === REQUEST ================================
  1273. 0x65, // b Destroy Queue
  1274. dwQueueId // d Queue ID
  1275. // === REPLY ==================================
  1276. );
  1277. (void) SetWin32ErrorFromNtStatus( NtStatus );
  1278. return MapNtStatus( NtStatus, NcpClassBindery );
  1279. }
  1280. //
  1281. // tommye MS 88021 / MCS
  1282. //
  1283. // Added the following two routines to allow the library user
  1284. // to obtain a NWCONN_HANDLE given a ObjectHandle, then free that
  1285. // handle.
  1286. //
  1287. NWCONN_HANDLE NWAPI DLLEXPORT
  1288. NwNdsObjectHandleToConnHandle(
  1289. IN HANDLE ObjectHandle)
  1290. {
  1291. PNWC_SERVER_INFO pServerInfo;
  1292. LPNDS_OBJECT_PRIV pObject = (LPNDS_OBJECT_PRIV)ObjectHandle;
  1293. /** Allocate the NWCONN_HANDLE to return **/
  1294. pServerInfo = (PNWC_SERVER_INFO)LocalAlloc(LPTR, sizeof(NWC_SERVER_INFO));
  1295. if (pServerInfo == NULL) {
  1296. SetLastError( ERROR_NOT_ENOUGH_MEMORY );
  1297. return NULL;
  1298. }
  1299. /** Fill it in **/
  1300. pServerInfo->hConn = pObject->NdsTree;
  1301. /**
  1302. Fill in the server name, even though NWLoginToFileServer and
  1303. NWLogoutFromFileServer are the only calls that use it now.
  1304. **/
  1305. RtlInitUnicodeString(
  1306. &pServerInfo->ServerString,
  1307. pObject->szContainerName);
  1308. /**
  1309. Return the pointer to the block, which is our form of NWCONN_HANDLE.
  1310. The caller is responsible for calling NwNdsConnHandlFree when done.
  1311. **/
  1312. return (NWCONN_HANDLE)pServerInfo;
  1313. }
  1314. VOID NWAPI DLLEXPORT
  1315. NwNdsConnHandleFree(
  1316. IN NWCONN_HANDLE hConn)
  1317. {
  1318. if (hConn) {
  1319. PNWC_SERVER_INFO pServerInfo = (PNWC_SERVER_INFO)hConn;
  1320. /** Free the connection handle **/
  1321. LocalFree(pServerInfo);
  1322. }
  1323. /** All done **/
  1324. return;
  1325. }