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.

3688 lines
91 KiB

  1. /*++
  2. Copyright (c) 1991-1992 Microsoft Corporation
  3. Module Name:
  4. SrvStub.C
  5. Abstract:
  6. These are the server service API RPC client stubs.
  7. Author:
  8. Dan Lafferty (danl) 06-Feb-1991
  9. Environment:
  10. User Mode - Win32
  11. Revision History:
  12. 06-Feb-1991 Danl
  13. Created
  14. 07-Jun-1991 JohnRo
  15. Added downlevel support for NetServer APIs.
  16. Added NET_API_FUNCTION where necessary.
  17. 15-Jul-1991 RFirth
  18. Integrated RxNetShare routines into NetShare stubs
  19. 24-Jul-1991 JohnRo
  20. Implement downlevel NetConnectionEnum. Try using <netrpc.h> macros.
  21. 25-Jul-1991 JohnRo
  22. Quiet DLL stub debug output. Use NetRpc.h macros for NetServer APIs.
  23. 06-Sep-1991 JohnRo
  24. Downlevel NetFile APIs.
  25. 25-Sep-1991 JohnRo
  26. Use NetRpc.h macros for all other APIs, to quiet normal debug output.
  27. 07-Oct-1991 JohnRo
  28. RAID 3210: "NET FILE 0" causes assertion. (Was bug in NetFileGetInfo
  29. DLL stub.)
  30. 16-Oct-1991 JohnRo
  31. Implement remote NetSession APIs. Changed LPSTR to LPTSTR.
  32. 07-Nov-1991 JohnRo
  33. RAID 4186: assert in RxNetShareAdd and other DLL stub problems.
  34. 12-Nov-1991 JohnRo
  35. APIs in this file need SERVICE_SERVER started to run locally.
  36. 04-Dec-1991 JohnRo
  37. Change RxNetServerSetInfo() to new-style interface.
  38. Fixed bug in calling RxNetShareSetInfo().
  39. 09-May-1992 rfirth
  40. Resurrect NetStatisticsGet as NetServerStatisticsGet
  41. 5-Aug-1992 JohnsonA
  42. Added new share info level 502 to enable passing of security
  43. descriptors.
  44. 08-Sep-1992 JohnRo
  45. Fix NET_API_FUNCTION references.
  46. --*/
  47. //
  48. // INCLUDES
  49. //
  50. #include <nt.h> // DbgPrint prototype
  51. #include <ntrtl.h> // DbgPrint
  52. #include <rpc.h> // DataTypes and runtime APIs
  53. #include <srvsvc.h> // generated by the MIDL complier
  54. #include <rpcutil.h> // GENERIC_ENUM_STRUCT
  55. #include <lmcons.h> // NET_API_STATUS
  56. #include <debuglib.h> // (needed by netrpc.h)
  57. #include <lmsvc.h> // (needed by netrpc.h)
  58. #include <netdebug.h> // (needed by netrpc.h)
  59. #include <lmerr.h> // NetError codes
  60. #include <netlib.h> // NetpIsServiceStarted().
  61. #include <netlibnt.h> // NetpNtStatusToApiStatus
  62. #include <netrpc.h> // NET_REMOTE_ macros.
  63. #include <lmremutl.h> // SUPPORTS_RPC
  64. #include <lmshare.h> // Required by rxsess.h.
  65. #include <rap.h> // Needed by <rxserver.h>.
  66. #include <rxconn.h> // RxNetConnection routines.
  67. #include <rxfile.h> // RxNetFile routines.
  68. #include <rxremutl.h> // RxNetRemoteTOD
  69. #include <rxserver.h> // RxNetServer routines.
  70. #include <rxsess.h> // RxNetSession routines.
  71. #include <rxshare.h> // RxNetShare routines
  72. #include <icanon.h> // NetpIsRemote
  73. #include <netstats.h> // NetServerStatisticsGet private prototype
  74. #include <rxstats.h> // RxNetStatisticsGet (down-level)
  75. #include <netcan.h> // prototypes for Netps canonicalization functions
  76. #include <rxcanon.h> // prototypes for down-level canonicalization functions
  77. #include <tstr.h>
  78. #include "cscp.h"
  79. #define SET_ERROR_PARAMETER(a) \
  80. if ( ARGUMENT_PRESENT( parm_err ) ) { *parm_err = a; }
  81. NET_API_STATUS NET_API_FUNCTION
  82. NetCharDevControl (
  83. IN LPCWSTR servername,
  84. IN LPCWSTR devname,
  85. IN DWORD opcode
  86. )
  87. /*++
  88. Routine Description:
  89. This is the DLL entrypoint for NetCharDevControl.
  90. Arguments:
  91. servername --A pointer to an ASCIIZ string containing the name of
  92. the remote server on which the function is to execute. A NULL
  93. pointer or string specifies the local machine.
  94. devname --A pointer to the ASCIIZ string containing the name of
  95. the device to control
  96. opcode --Control opcode: currently defined are:
  97. CHARDEV_CLOSE for the device closed.
  98. Return Value:
  99. --*/
  100. {
  101. NET_API_STATUS apiStatus;
  102. NET_REMOTE_TRY_RPC
  103. apiStatus = NetrCharDevControl (
  104. (LPWSTR)servername,
  105. (LPWSTR)devname,
  106. opcode);
  107. NET_REMOTE_RPC_FAILED(
  108. "NetCharDevControl",
  109. servername,
  110. apiStatus,
  111. NET_REMOTE_FLAG_NORMAL,
  112. SERVICE_SERVER)
  113. apiStatus = ERROR_NOT_SUPPORTED;
  114. NET_REMOTE_END
  115. return(apiStatus);
  116. } // NetCharDevControl
  117. NET_API_STATUS NET_API_FUNCTION
  118. NetCharDevEnum (
  119. IN LPCWSTR servername,
  120. IN DWORD level,
  121. OUT LPBYTE *bufptr,
  122. IN DWORD prefmaxlen,
  123. OUT LPDWORD entriesread,
  124. OUT LPDWORD totalentries,
  125. IN OUT LPDWORD resume_handle
  126. )
  127. /*++
  128. Routine Description:
  129. This is the DLL entrypoint for NetCharDevEnum.
  130. Arguments:
  131. servername --A pointer to an ASCIIZ string containing the name of
  132. the remote server on which the function is to execute. A NULL
  133. pointer or string specifies the local machine.
  134. level --Level of information required. 0 and 1 are valid.
  135. bufptr --On return a pointer to the return information structure
  136. is returned in the address pointed to by bufptr.
  137. prefmaxlen --Prefered maximum length of returned data (in 8-bit
  138. bytes). 0xffffffff specifies no limit.
  139. entriesread --On return the actual enumerated element count is
  140. located in the DWORD pointed to by entriesread.
  141. totalentries --On return the total entries available to be
  142. enumerated is located in the DWORD pointed to by
  143. totalentries.
  144. resumehandle --On return, a resume handle is stored in the DWORD
  145. pointed to by resumehandle, and is used to continue an
  146. existing character device search. The handle should be zero
  147. on the first call and left unchanged for subsequent calls. If
  148. resumehandle is NULL, then no resume handle is stored..
  149. Return Value:
  150. --*/
  151. {
  152. NET_API_STATUS apiStatus;
  153. GENERIC_INFO_CONTAINER genericInfoContainer;
  154. GENERIC_ENUM_STRUCT infoStruct;
  155. genericInfoContainer.Buffer = NULL;
  156. genericInfoContainer.EntriesRead = 0;
  157. infoStruct.Container = &genericInfoContainer;
  158. infoStruct.Level = level;
  159. NET_REMOTE_TRY_RPC
  160. apiStatus = NetrCharDevEnum (
  161. (LPWSTR)servername,
  162. (LPCHARDEV_ENUM_STRUCT)&infoStruct,
  163. prefmaxlen,
  164. totalentries,
  165. resume_handle);
  166. if (genericInfoContainer.Buffer != NULL) {
  167. *bufptr = (LPBYTE)genericInfoContainer.Buffer;
  168. *entriesread = genericInfoContainer.EntriesRead;
  169. } else {
  170. *bufptr = NULL;
  171. *entriesread = 0;
  172. }
  173. NET_REMOTE_RPC_FAILED(
  174. "NetCharDevEnum",
  175. servername,
  176. apiStatus,
  177. NET_REMOTE_FLAG_NORMAL,
  178. SERVICE_SERVER)
  179. apiStatus = ERROR_NOT_SUPPORTED;
  180. NET_REMOTE_END
  181. return(apiStatus);
  182. } // NetCharDevEnum
  183. NET_API_STATUS NET_API_FUNCTION
  184. NetCharDevGetInfo (
  185. IN LPCWSTR servername,
  186. IN LPCWSTR devname,
  187. IN DWORD level,
  188. OUT LPBYTE *bufptr
  189. )
  190. /*++
  191. Routine Description:
  192. This is the DLL entrypoint for NetCharDevGetInfo.
  193. Arguments:
  194. servername --A pointer to an ASCIIZ string containing the name of
  195. the remote server on which the function is to execute. A NULL
  196. pointer or string specifies the local machine.
  197. devname --A pointer to the ASCIIZ string containing the name of
  198. the device to return information on.
  199. level --Level of information required. 0 and 1 are valid.
  200. bufptr --On return a pointer to the return information structure
  201. is returned in the address pointed to by bufptr.
  202. Return Value:
  203. --*/
  204. {
  205. NET_API_STATUS apiStatus;
  206. *bufptr = NULL; // Must be NULL so RPC knows to till it in.
  207. NET_REMOTE_TRY_RPC
  208. apiStatus = NetrCharDevGetInfo (
  209. (LPWSTR)servername,
  210. (LPWSTR)devname,
  211. level,
  212. (LPCHARDEV_INFO) bufptr);
  213. NET_REMOTE_RPC_FAILED(
  214. "NetCharDevGetInfo",
  215. servername,
  216. apiStatus,
  217. NET_REMOTE_FLAG_NORMAL,
  218. SERVICE_SERVER)
  219. apiStatus = ERROR_NOT_SUPPORTED;
  220. NET_REMOTE_END
  221. return(apiStatus);
  222. } // NetCharDevGetInfo
  223. NET_API_STATUS NET_API_FUNCTION
  224. NetCharDevQEnum (
  225. IN LPCWSTR servername,
  226. IN LPCWSTR username,
  227. IN DWORD level,
  228. OUT LPBYTE *bufptr,
  229. IN DWORD prefmaxlen,
  230. OUT LPDWORD entriesread,
  231. OUT LPDWORD totalentries,
  232. IN OUT LPDWORD resume_handle
  233. )
  234. /*++
  235. Routine Description:
  236. This is the DLL entrypoint for NetCharDevQEnum.
  237. Arguments:
  238. servername --A pointer to an ASCIIZ string containing the name of
  239. the remote server on which the function is to execute. A NULL
  240. pointer or string specifies the local machine.
  241. username --A pointer to an ASCIIZ string containing an a username
  242. for the active queues of interest. This parameter is
  243. optional, if NULL then all device queues are enumerated.
  244. level --Level of information required. 0 and 1 are valid.
  245. bufptr --On return a pointer to the return information structure
  246. is returned in the address pointed to by bufptr.
  247. prefmaxlen --Prefered maximum length of returned data (in 8-bit
  248. bytes). 0xffffffff specifies no limit.
  249. entriesread --On return the actual enumerated element count is
  250. located in the DWORD pointed to by entriesread.
  251. totalentries --On return the total entries available to be
  252. enumerated is located in the DWORD pointed to by
  253. totalentries.
  254. resumehandle --On return, a resume handle is stored in the DWORD
  255. pointed to by resumehandle, and is used to continue an
  256. existing character device queue search. The handle should be
  257. Return Value:
  258. --*/
  259. {
  260. NET_API_STATUS apiStatus;
  261. GENERIC_INFO_CONTAINER genericInfoContainer;
  262. GENERIC_ENUM_STRUCT infoStruct;
  263. genericInfoContainer.Buffer = NULL;
  264. genericInfoContainer.EntriesRead = 0;
  265. infoStruct.Container = &genericInfoContainer;
  266. infoStruct.Level = level;
  267. NET_REMOTE_TRY_RPC
  268. apiStatus = NetrCharDevQEnum (
  269. (LPWSTR)servername,
  270. (LPWSTR)username,
  271. (LPCHARDEVQ_ENUM_STRUCT) &infoStruct,
  272. prefmaxlen,
  273. totalentries,
  274. resume_handle);
  275. if (genericInfoContainer.Buffer != NULL) {
  276. *bufptr = (LPBYTE)genericInfoContainer.Buffer;
  277. *entriesread = genericInfoContainer.EntriesRead;
  278. } else {
  279. *bufptr = NULL;
  280. *entriesread = 0;
  281. }
  282. NET_REMOTE_RPC_FAILED(
  283. "NetCharDevQEnum",
  284. servername,
  285. apiStatus,
  286. NET_REMOTE_FLAG_NORMAL,
  287. SERVICE_SERVER)
  288. apiStatus = ERROR_NOT_SUPPORTED;
  289. NET_REMOTE_END
  290. return(apiStatus);
  291. } // NetCharDevQEnum
  292. NET_API_STATUS NET_API_FUNCTION
  293. NetCharDevQGetInfo (
  294. IN LPCWSTR servername,
  295. IN LPCWSTR queuename,
  296. IN LPCWSTR username,
  297. IN DWORD level,
  298. OUT LPBYTE *bufptr
  299. )
  300. /*++
  301. Routine Description:
  302. This is the DLL entrypoint for NetCharDevQGetInfo.
  303. Arguments:
  304. servername --A pointer to an ASCIIZ string containing the name of
  305. the remote server on which the function is to execute. A NULL
  306. pointer or string specifies the local machine.
  307. queuename --A pointer to an ASCIIZ string containing the name of
  308. the queue to return information on.
  309. username --A pointer to an ASCIIZ string containing the username
  310. of the a user whose job of of interest for the cq1_numahead
  311. count.
  312. level --Level of information required. 0 and 1 are valid.
  313. bufptr --On return a pointer to the return information structure
  314. is returned in the address pointed to by bufptr.
  315. Return Value:
  316. --*/
  317. {
  318. NET_API_STATUS apiStatus;
  319. *bufptr = NULL; // Must be NULL so RPC knows to till it in.
  320. NET_REMOTE_TRY_RPC
  321. apiStatus = NetrCharDevQGetInfo (
  322. (LPWSTR)servername,
  323. (LPWSTR)queuename,
  324. (LPWSTR)username,
  325. level,
  326. (LPCHARDEVQ_INFO) bufptr);
  327. NET_REMOTE_RPC_FAILED(
  328. "NetCharDevQGetInfo",
  329. servername,
  330. apiStatus,
  331. NET_REMOTE_FLAG_NORMAL,
  332. SERVICE_SERVER)
  333. apiStatus = ERROR_NOT_SUPPORTED;
  334. NET_REMOTE_END
  335. return(apiStatus);
  336. } // NetCharDevQGetInfo
  337. NET_API_STATUS NET_API_FUNCTION
  338. NetCharDevQPurge (
  339. IN LPCWSTR servername,
  340. IN LPCWSTR queuename
  341. )
  342. /*++
  343. Routine Description:
  344. This is the DLL entrypoint for NetCharDevQPurge.
  345. Arguments:
  346. servername --A pointer to an ASCIIZ string containing the name of
  347. the remote server on which the function is to execute. A NULL
  348. pointer or string specifies the local machine.
  349. queuename --A pointer to an ASCIIZ string containing the name of
  350. the queue to be purged.
  351. Return Value:
  352. --*/
  353. {
  354. NET_API_STATUS apiStatus;
  355. NET_REMOTE_TRY_RPC
  356. apiStatus = NetrCharDevQPurge (
  357. (LPWSTR)servername,
  358. (LPWSTR)queuename);
  359. NET_REMOTE_RPC_FAILED(
  360. "NetCharDevQPurge",
  361. servername,
  362. apiStatus,
  363. NET_REMOTE_FLAG_NORMAL,
  364. SERVICE_SERVER)
  365. apiStatus = ERROR_NOT_SUPPORTED;
  366. NET_REMOTE_END
  367. return(apiStatus);
  368. } // NetCharDevQPurge
  369. NET_API_STATUS NET_API_FUNCTION
  370. NetCharDevQPurgeSelf (
  371. IN LPCWSTR servername,
  372. IN LPCWSTR queuename,
  373. IN LPCWSTR computername
  374. )
  375. /*++
  376. Routine Description:
  377. This is the DLL entrypoint for NetCharDevQPurgeSelf.
  378. Arguments:
  379. servername --A pointer to an ASCIIZ string containing the name of
  380. the remote server on which the function is to execute. A NULL
  381. pointer or string specifies the local machine.
  382. queuename --A pointer to an ASCIIZ string containing the name of
  383. the queue to be purged of pending entries from the specified
  384. computer.
  385. Return Value:
  386. --*/
  387. {
  388. NET_API_STATUS apiStatus;
  389. NET_REMOTE_TRY_RPC
  390. apiStatus = NetrCharDevQPurgeSelf (
  391. (LPWSTR)servername,
  392. (LPWSTR)queuename,
  393. (LPWSTR)computername);
  394. NET_REMOTE_RPC_FAILED(
  395. "NetCharDevQPurgeSelf",
  396. servername,
  397. apiStatus,
  398. NET_REMOTE_FLAG_NORMAL,
  399. SERVICE_SERVER)
  400. apiStatus = ERROR_NOT_SUPPORTED;
  401. NET_REMOTE_END
  402. return(apiStatus);
  403. } // NetCharDevQPurgeSelf
  404. NET_API_STATUS NET_API_FUNCTION
  405. NetCharDevQSetInfo (
  406. IN LPCWSTR servername,
  407. IN LPCWSTR queuename,
  408. IN DWORD level,
  409. IN LPBYTE buf,
  410. OUT LPDWORD parm_err
  411. )
  412. /*++
  413. Routine Description:
  414. This is the DLL entrypoint for NetCharDevQSetInfo.
  415. Arguments:
  416. servername --A pointer to an ASCIIZ string containing the name of
  417. the remote server on which the function is to execute. A NULL
  418. pointer or string specifies the local machine.
  419. queuename --A pointer to an ASCIIZ string containing the name of
  420. the queue to set information on.
  421. level --Level of information to set.
  422. buf --A pointer to a buffer containing the chardev information.
  423. If parmnum is non zero then the buffer contains only the
  424. appropriate data for the specific element. If parmnum is
  425. zero, then the buffer contains the whole chardev information
  426. structure.
  427. parm_err --Optional pointer to a DWORD to return the index of the
  428. first parameter in error when ERROR_INVALID_PARAMETER is
  429. returned. If NULL the parameter is not returned on error.
  430. Return Value:
  431. --*/
  432. {
  433. NET_API_STATUS apiStatus;
  434. NET_REMOTE_TRY_RPC
  435. apiStatus = NetrCharDevQSetInfo (
  436. (LPWSTR)servername,
  437. (LPWSTR)queuename,
  438. level,
  439. (LPCHARDEVQ_INFO) &buf,
  440. parm_err);
  441. NET_REMOTE_RPC_FAILED(
  442. "NetCharDevQSetInfo",
  443. servername,
  444. apiStatus,
  445. NET_REMOTE_FLAG_NORMAL,
  446. SERVICE_SERVER)
  447. apiStatus = ERROR_NOT_SUPPORTED;
  448. NET_REMOTE_END
  449. return(apiStatus);
  450. } // NetCharDevQSetInfo
  451. NET_API_STATUS NET_API_FUNCTION
  452. NetConnectionEnum (
  453. IN LPTSTR servername,
  454. IN LPTSTR qualifier,
  455. IN DWORD level,
  456. OUT LPBYTE *bufptr,
  457. IN DWORD prefmaxlen,
  458. OUT LPDWORD entriesread,
  459. OUT LPDWORD totalentries,
  460. IN OUT LPDWORD resume_handle
  461. )
  462. /*++
  463. Routine Description:
  464. This is the DLL entrypoint for NetConnectionEnum.
  465. Arguments:
  466. servername --A pointer to an ASCIIZ string containing the name of
  467. the remote server on which the function is to execute. A NULL
  468. pointer or string specifies the local machine.
  469. qualifier --A pointer to an ASCIIZ string containing a sharename
  470. or computername for the connections of interest. If it is a
  471. sharename, then all the connections made to that sharename
  472. are listed. If it is a computername (i.e. it starts with two
  473. backslash characters), then NetConnectionEnum lists all
  474. connections made from that computer to the server specified.
  475. level --Level of information required. 0 and 1 are valid.
  476. bufptr --On return a pointer to the return information structure
  477. is returned in the address pointed to by bufptr.
  478. prefmaxlen --Prefered maximum length of returned data (in 8-bit
  479. bytes). 0xffffffff specifies no limit.
  480. entriesread --On return the actual enumerated element count is
  481. located in the DWORD pointed to by entriesread.
  482. Return Value:
  483. --*/
  484. {
  485. NET_API_STATUS apiStatus;
  486. GENERIC_INFO_CONTAINER genericInfoContainer;
  487. GENERIC_ENUM_STRUCT infoStruct;
  488. genericInfoContainer.Buffer = NULL;
  489. genericInfoContainer.EntriesRead = 0;
  490. infoStruct.Container = &genericInfoContainer;
  491. infoStruct.Level = level;
  492. NET_REMOTE_TRY_RPC
  493. apiStatus = NetrConnectionEnum (
  494. servername,
  495. qualifier,
  496. (LPCONNECT_ENUM_STRUCT)&infoStruct,
  497. prefmaxlen,
  498. totalentries,
  499. resume_handle);
  500. if (genericInfoContainer.Buffer != NULL) {
  501. *bufptr = (LPBYTE)genericInfoContainer.Buffer;
  502. *entriesread = genericInfoContainer.EntriesRead;
  503. } else {
  504. *bufptr = NULL;
  505. *entriesread = 0;
  506. }
  507. NET_REMOTE_RPC_FAILED(
  508. "NetConnectionEnum",
  509. servername,
  510. apiStatus,
  511. NET_REMOTE_FLAG_NORMAL,
  512. SERVICE_SERVER)
  513. //
  514. // Try call to downlevel.
  515. //
  516. apiStatus = RxNetConnectionEnum(
  517. servername,
  518. qualifier,
  519. level,
  520. bufptr,
  521. prefmaxlen,
  522. entriesread,
  523. totalentries,
  524. resume_handle
  525. );
  526. NET_REMOTE_END
  527. return(apiStatus);
  528. } // NetConnectionEnum
  529. NET_API_STATUS NET_API_FUNCTION
  530. NetFileClose (
  531. IN LPTSTR servername,
  532. IN DWORD fileid
  533. )
  534. /*++
  535. Routine Description:
  536. This is the DLL entrypoint for NetFileClose.
  537. Arguments:
  538. servername --A pointer to an ASCIIZ string containing the name of
  539. the remote server on which the function is to execute. A NULL
  540. pointer or string specifies the local machine.
  541. fileid --The fileid of the opened resource instance to be closed.
  542. Return Value:
  543. --*/
  544. {
  545. NET_API_STATUS apiStatus;
  546. NET_REMOTE_TRY_RPC
  547. apiStatus = NetrFileClose (
  548. servername,
  549. fileid);
  550. NET_REMOTE_RPC_FAILED(
  551. "NetFileClose",
  552. servername,
  553. apiStatus,
  554. NET_REMOTE_FLAG_NORMAL,
  555. SERVICE_SERVER)
  556. apiStatus = RxNetFileClose (
  557. servername,
  558. fileid);
  559. NET_REMOTE_END
  560. return(apiStatus);
  561. }
  562. NET_API_STATUS NET_API_FUNCTION
  563. NetFileEnum (
  564. IN LPTSTR servername,
  565. IN LPTSTR basepath,
  566. IN LPTSTR username,
  567. IN DWORD level,
  568. OUT LPBYTE *bufptr,
  569. IN DWORD prefmaxlen,
  570. OUT LPDWORD entriesread,
  571. OUT LPDWORD totalentries,
  572. IN OUT PDWORD_PTR resume_handle
  573. )
  574. /*++
  575. Routine Description:
  576. This is the DLL entrypoint for NetFileEnum.
  577. Arguments:
  578. servername --A pointer to an ASCIIZ string containing the name of
  579. the remote server on which the function is to execute. A NULL
  580. pointer or string specifies the local machine.
  581. basepath --A pointer to an ASCIIZ string containing a qualifier
  582. for the returned information. If NULL then all open resources
  583. are enumerated, else only resources which have basepath as a
  584. prefix are enumerated.
  585. username --A pointer to an ASCIIZ string that specifies the name
  586. of the user. If not NULL, username serves as a qualifier to
  587. the ennumeration. The files returned are limited to those
  588. that have usernames matching the qualifier. If username is
  589. NULL, no username qualifier is used.
  590. level --Level of information required. 2 and 3 are valid.
  591. bufptr --On return a pointer to the return information structure
  592. is returned in the address pointed to by bufptr.
  593. prefmaxlen --Prefered maximum length of returned data (in 8-bit
  594. bytes). 0xffffffff specifies no limit.
  595. entriesread --On return the actual enumerated element count is
  596. located in the DWORD pointed to by entriesread.
  597. totalentries --On return the total entries available to be
  598. enumerated is located in the DWORD pointed to by
  599. totalentries.
  600. resumehandle --On return, a resume handle is stored in the DWORD
  601. pointed to by resumehandle, and is used to continue an
  602. existing file search. The handle should be zero on the first
  603. call and left unchanged for subsequent calls. If resumehandle
  604. is NULL, then no resume handle is stored..
  605. Return Value:
  606. --*/
  607. {
  608. NET_API_STATUS apiStatus;
  609. GENERIC_INFO_CONTAINER genericInfoContainer;
  610. GENERIC_ENUM_STRUCT infoStruct;
  611. genericInfoContainer.Buffer = NULL;
  612. genericInfoContainer.EntriesRead = 0;
  613. infoStruct.Container = &genericInfoContainer;
  614. infoStruct.Level = level;
  615. NET_REMOTE_TRY_RPC
  616. //
  617. // NetrFileEnum's resume_handle parm is a true index that will remain
  618. // 32 bits wide for on-the-wire compatibility. Thus, the cast to
  619. // (PDWORD) here works.
  620. //
  621. apiStatus = NetrFileEnum (
  622. servername,
  623. basepath,
  624. username,
  625. (LPFILE_ENUM_STRUCT) &infoStruct,
  626. prefmaxlen,
  627. totalentries,
  628. (PDWORD)resume_handle);
  629. if (genericInfoContainer.Buffer != NULL) {
  630. *bufptr = (LPBYTE)genericInfoContainer.Buffer;
  631. *entriesread = genericInfoContainer.EntriesRead;
  632. } else {
  633. *bufptr = NULL;
  634. *entriesread = 0;
  635. }
  636. NET_REMOTE_RPC_FAILED(
  637. "NetFileEnum",
  638. servername,
  639. apiStatus,
  640. NET_REMOTE_FLAG_NORMAL,
  641. SERVICE_SERVER)
  642. apiStatus = RxNetFileEnum(
  643. servername,
  644. basepath,
  645. username,
  646. level,
  647. bufptr,
  648. prefmaxlen,
  649. entriesread,
  650. totalentries,
  651. resume_handle);
  652. NET_REMOTE_END
  653. return(apiStatus);
  654. } // NetFileEnum
  655. NET_API_STATUS NET_API_FUNCTION
  656. NetFileGetInfo (
  657. IN LPTSTR servername,
  658. IN DWORD fileid,
  659. IN DWORD level,
  660. OUT LPBYTE *bufptr
  661. )
  662. /*++
  663. Routine Description:
  664. This is the DLL entrypoint for NetFileGetInfo.
  665. Arguments:
  666. servername --A pointer to an ASCIIZ string containing the name of
  667. the remote server on which the function is to execute. A NULL
  668. pointer or string specifies the local machine.
  669. fileid --The fileid of the open resource to return information
  670. on. The fileid value must be that returned in a previous
  671. enumeration call.
  672. level --Level of information required. 2 and 3 are valid.
  673. bufptr --On return a pointer to the return information structure
  674. is returned in the address pointed to by bufptr.
  675. Return Value:
  676. --*/
  677. {
  678. NET_API_STATUS apiStatus;
  679. *bufptr = NULL; // Must be NULL so RPC knows to fill it in.
  680. NET_REMOTE_TRY_RPC
  681. apiStatus = NetrFileGetInfo (
  682. servername,
  683. fileid,
  684. level,
  685. (LPFILE_INFO) bufptr);
  686. NET_REMOTE_RPC_FAILED(
  687. "NetFileGetInfo",
  688. servername,
  689. apiStatus,
  690. NET_REMOTE_FLAG_NORMAL,
  691. SERVICE_SERVER)
  692. apiStatus = RxNetFileGetInfo (
  693. servername,
  694. fileid,
  695. level,
  696. bufptr);
  697. NET_REMOTE_END
  698. return(apiStatus);
  699. } // NetFileGetInfo
  700. NET_API_STATUS NET_API_FUNCTION
  701. NetSessionDel (
  702. IN LPTSTR servername,
  703. IN LPTSTR clientname,
  704. IN LPTSTR username
  705. )
  706. /*++
  707. Routine Description:
  708. This is the DLL entrypoint for NetSessionDel.
  709. Arguments:
  710. servername --A pointer to an ASCIIZ string containing the name of
  711. the remote server on which the function is to execute. A NULL
  712. pointer or string specifies the local machine.
  713. clientname --A pointer to an ASCIIZ string containing the
  714. computername of the client to disconnect.
  715. username --A pointer to an ASCIIZ string containing the name of
  716. the user whose session is to be terminated. A NULL indicates
  717. that all users' sessions from the computername specified are
  718. to be terminated.
  719. Return Value:
  720. --*/
  721. {
  722. NET_API_STATUS apiStatus;
  723. NET_REMOTE_TRY_RPC
  724. apiStatus = NetrSessionDel (
  725. servername,
  726. clientname,
  727. username);
  728. NET_REMOTE_RPC_FAILED("NetSessionDel", servername, apiStatus,
  729. NET_REMOTE_FLAG_NORMAL,
  730. SERVICE_SERVER )
  731. //
  732. // Call downlevel version of the API.
  733. //
  734. apiStatus = RxNetSessionDel (
  735. servername,
  736. clientname,
  737. username);
  738. NET_REMOTE_END
  739. return(apiStatus);
  740. } // NetSessionDel
  741. NET_API_STATUS NET_API_FUNCTION
  742. NetSessionEnum (
  743. IN LPTSTR servername,
  744. IN LPTSTR clientname,
  745. IN LPTSTR username,
  746. IN DWORD level,
  747. OUT LPBYTE *bufptr,
  748. IN DWORD prefmaxlen,
  749. OUT LPDWORD entriesread,
  750. OUT LPDWORD totalentries,
  751. IN OUT LPDWORD resume_handle
  752. )
  753. /*++
  754. Routine Description:
  755. This is the DLL entrypoint for NetSessionEnum.
  756. Arguments:
  757. servername --A pointer to an ASCIIZ string containing the name of
  758. the remote server on which the function is to execute. A NULL
  759. pointer or string specifies the local machine.
  760. clientname --A pointer to an ASCIIZ string containing the name of
  761. the computer session for which information is to be returned.
  762. A NULL pointer or string specifies that all computer sessions
  763. on the server are to be ennumerated.
  764. username --A pointer to an ASCIIZ string containing the name of
  765. the the user for which to ennumerate the sessions. A NULL
  766. pointer or string specifies that sessions for all users are
  767. to be ennumerated.
  768. level --Level of information required. 0, 1, 2 and 10 are valid.
  769. bufptr --On return a pointer to the return information structure
  770. is returned in the address pointed to by bufptr.
  771. prefmaxlen --Prefered maximum length of returned data (in 8-bit
  772. bytes). 0xffffffff specifies no limit.
  773. entriesread --On return the actual enumerated element count is
  774. located in the DWORD pointed to by entriesread.
  775. totalentries --On return the total entries available to be
  776. enumerated is located in the DWORD pointed to by
  777. totalentries.
  778. resumehandle --On return, a resume handle is stored in the DWORD
  779. pointed to by resumehandle, and is used to continue an
  780. existing session search. The handle should be zero on the
  781. first call and left unchanged for subsequent calls. If
  782. resumehandle is NULL, then no resume handle is stored.
  783. Return Value:
  784. --*/
  785. {
  786. NET_API_STATUS apiStatus;
  787. GENERIC_INFO_CONTAINER genericInfoContainer;
  788. GENERIC_ENUM_STRUCT infoStruct;
  789. genericInfoContainer.Buffer = NULL;
  790. genericInfoContainer.EntriesRead = 0;
  791. infoStruct.Container = &genericInfoContainer;
  792. infoStruct.Level = level;
  793. NET_REMOTE_TRY_RPC
  794. apiStatus = NetrSessionEnum (
  795. servername,
  796. clientname,
  797. username,
  798. (PSESSION_ENUM_STRUCT) &infoStruct,
  799. prefmaxlen,
  800. totalentries,
  801. resume_handle);
  802. if (genericInfoContainer.Buffer != NULL) {
  803. *bufptr = (LPBYTE)genericInfoContainer.Buffer;
  804. *entriesread = genericInfoContainer.EntriesRead;
  805. } else {
  806. *bufptr = NULL;
  807. *entriesread = 0;
  808. }
  809. NET_REMOTE_RPC_FAILED("NetSessionEnum", servername, apiStatus,
  810. NET_REMOTE_FLAG_NORMAL,
  811. SERVICE_SERVER )
  812. //
  813. // Call downlevel version of the API.
  814. //
  815. apiStatus = RxNetSessionEnum (
  816. servername,
  817. clientname,
  818. username,
  819. level,
  820. bufptr,
  821. prefmaxlen,
  822. entriesread,
  823. totalentries,
  824. resume_handle);
  825. NET_REMOTE_END
  826. return(apiStatus);
  827. } // NetSessionEnum
  828. NET_API_STATUS NET_API_FUNCTION
  829. NetSessionGetInfo (
  830. IN LPTSTR servername,
  831. IN LPTSTR clientname,
  832. IN LPTSTR username,
  833. IN DWORD level,
  834. OUT LPBYTE *bufptr
  835. )
  836. /*++
  837. Routine Description:
  838. This is the DLL entrypoint for NetSessionEnum.
  839. Arguments:
  840. servername --A pointer to an ASCIIZ string containing the name of
  841. the remote server on which the function is to execute. A NULL
  842. pointer or string specifies the local machine.
  843. clientname --A pointer to an ASCIIZ string containing the name of
  844. the computer session for which information is to be returned.
  845. This field cannot be NULL.
  846. username --A pointer to an ASCIIZ string containing the name of
  847. the the user for which to ennumerate the sessions. This field
  848. cannot be NULL.
  849. level --Level of information required. 0, 1, 2 and 10 are valid.
  850. bufptr --On return a pointer to the return information structure
  851. is returned in the address pointed to by bufptr.
  852. Return Value:
  853. --*/
  854. {
  855. NET_API_STATUS apiStatus;
  856. GENERIC_INFO_CONTAINER genericInfoContainer;
  857. GENERIC_ENUM_STRUCT infoStruct;
  858. DWORD totalentries;
  859. if ( clientname == NULL || username == NULL ) {
  860. return ERROR_INVALID_PARAMETER;
  861. }
  862. genericInfoContainer.Buffer = NULL;
  863. genericInfoContainer.EntriesRead = 0;
  864. infoStruct.Container = &genericInfoContainer;
  865. infoStruct.Level = level;
  866. NET_REMOTE_TRY_RPC
  867. apiStatus = NetrSessionEnum (
  868. servername,
  869. clientname,
  870. username,
  871. (PSESSION_ENUM_STRUCT) &infoStruct,
  872. (DWORD)-1,
  873. &totalentries,
  874. NULL);
  875. if (genericInfoContainer.Buffer != NULL) {
  876. *bufptr = (LPBYTE)genericInfoContainer.Buffer;
  877. } else {
  878. *bufptr = NULL;
  879. if ( apiStatus == NO_ERROR ) {
  880. return NERR_ClientNameNotFound;
  881. }
  882. }
  883. NET_REMOTE_RPC_FAILED("NetSessionGetInfo", servername, apiStatus,
  884. NET_REMOTE_FLAG_NORMAL,
  885. SERVICE_SERVER )
  886. //
  887. // Call downlevel version of the API.
  888. //
  889. apiStatus = RxNetSessionGetInfo (
  890. servername,
  891. clientname,
  892. username,
  893. level,
  894. bufptr);
  895. NET_REMOTE_END
  896. return(apiStatus);
  897. } // NetSessionGetInfo
  898. NET_API_STATUS NET_API_FUNCTION
  899. NetShareAdd (
  900. IN LPTSTR servername,
  901. IN DWORD level,
  902. IN LPBYTE buf,
  903. OUT LPDWORD parm_err
  904. )
  905. /*++
  906. Routine Description:
  907. This is the DLL entrypoint for NetShareAdd. Only levels 2 and 502
  908. are allowed.
  909. Arguments:
  910. servername --A pointer to an ASCIIZ string containing the name of
  911. the remote server on which the function is to execute. A NULL
  912. pointer or string specifies the local machine.
  913. level --Level of information provided. Must be 2.
  914. buf --A pointer to a buffer containing the share information
  915. structure.
  916. parm_err --Optional pointer to a DWORD to return the index of the
  917. first parameter in error when ERROR_INVALID_PARAMETER is
  918. returned. If NULL the parameter is not returned on error.
  919. Return Value:
  920. --*/
  921. {
  922. NET_API_STATUS apiStatus;
  923. NTSTATUS status;
  924. ULONG SDLength = 0;
  925. ULONG oldSDLength;
  926. PSECURITY_DESCRIPTOR securityDescriptor = NULL;
  927. PSECURITY_DESCRIPTOR oldSecurityDescriptor = NULL;
  928. //
  929. // do the parameter validation here - this way we only need do it once and
  930. // in a centralized place
  931. //
  932. if (level != 2 && level != 502) {
  933. return ERROR_INVALID_LEVEL;
  934. }
  935. NET_REMOTE_TRY_RPC
  936. if ( level == 502 ) {
  937. PSHARE_INFO_502 shi502 = (LPSHARE_INFO_502) buf;
  938. //
  939. // Save this. We need to restore this later.
  940. //
  941. oldSecurityDescriptor = shi502->shi502_security_descriptor;
  942. oldSDLength = shi502->shi502_reserved;
  943. if ( oldSecurityDescriptor != NULL ) {
  944. if ( !RtlValidSecurityDescriptor( oldSecurityDescriptor) ) {
  945. SET_ERROR_PARAMETER( SHARE_FILE_SD_PARMNUM );
  946. return ERROR_INVALID_PARAMETER;
  947. }
  948. //
  949. // Make a self relative security descriptor for use in the
  950. // RPC call..
  951. //
  952. status = RtlMakeSelfRelativeSD(
  953. oldSecurityDescriptor,
  954. NULL,
  955. &SDLength
  956. );
  957. if (status != STATUS_BUFFER_TOO_SMALL) {
  958. SET_ERROR_PARAMETER( SHARE_FILE_SD_PARMNUM );
  959. return(ERROR_INVALID_PARAMETER);
  960. } else {
  961. securityDescriptor = MIDL_user_allocate( SDLength );
  962. if ( securityDescriptor == NULL) {
  963. return ERROR_NOT_ENOUGH_MEMORY;
  964. } else {
  965. //
  966. // make an appropriate self-relative security descriptor
  967. //
  968. status = RtlMakeSelfRelativeSD(
  969. oldSecurityDescriptor,
  970. (PSECURITY_DESCRIPTOR) securityDescriptor,
  971. &SDLength
  972. );
  973. if ( !NT_SUCCESS(status) ) {
  974. MIDL_user_free( securityDescriptor );
  975. SET_ERROR_PARAMETER( SHARE_FILE_SD_PARMNUM );
  976. return(ERROR_INVALID_PARAMETER);
  977. }
  978. shi502->shi502_security_descriptor = securityDescriptor;
  979. shi502->shi502_reserved = SDLength;
  980. }
  981. }
  982. } else {
  983. shi502->shi502_reserved = 0;
  984. }
  985. }
  986. apiStatus = NetrShareAdd (
  987. servername,
  988. level,
  989. (LPSHARE_INFO) &buf,
  990. parm_err);
  991. if ( securityDescriptor != NULL ) {
  992. //
  993. // restore old values
  994. //
  995. PSHARE_INFO_502 shi502 = (LPSHARE_INFO_502) buf;
  996. shi502->shi502_security_descriptor = oldSecurityDescriptor;
  997. shi502->shi502_reserved = oldSDLength;
  998. MIDL_user_free( securityDescriptor );
  999. }
  1000. NET_REMOTE_RPC_FAILED(
  1001. "NetShareAdd",
  1002. servername,
  1003. apiStatus,
  1004. NET_REMOTE_FLAG_NORMAL,
  1005. SERVICE_SERVER)
  1006. //
  1007. // Call downlevel server.
  1008. //
  1009. if ( level != 502 ) {
  1010. apiStatus = RxNetShareAdd(
  1011. servername,
  1012. 2,
  1013. buf,
  1014. parm_err
  1015. );
  1016. } else {
  1017. apiStatus = ERROR_NOT_SUPPORTED;
  1018. }
  1019. NET_REMOTE_END
  1020. return(apiStatus);
  1021. } // NetShareAdd
  1022. NET_API_STATUS NET_API_FUNCTION
  1023. NetShareCheck (
  1024. IN LPTSTR servername,
  1025. IN LPTSTR device,
  1026. OUT LPDWORD type
  1027. )
  1028. /*++
  1029. Routine Description:
  1030. This is the DLL entrypoint for NetShareCheck
  1031. Arguments:
  1032. servername --A pointer to an ASCIIZ string containing the name of
  1033. the remote server on which the function is to execute. A NULL
  1034. pointer or string specifies the local machine.
  1035. device --A pointer to an ASCIIZ string containing the name of the
  1036. device to check for shared access.
  1037. type --On return the address pointed to by the type parameter
  1038. contains the type of share the device is offered with. This
  1039. field is only set if success was returned.
  1040. Return Value:
  1041. --*/
  1042. {
  1043. NET_API_STATUS apiStatus;
  1044. if (!(device && *device) || !type) {
  1045. return ERROR_INVALID_PARAMETER;
  1046. }
  1047. NET_REMOTE_TRY_RPC
  1048. apiStatus = NetrShareCheck (
  1049. servername,
  1050. device,
  1051. type);
  1052. NET_REMOTE_RPC_FAILED(
  1053. "NetShareCheck",
  1054. servername,
  1055. apiStatus,
  1056. NET_REMOTE_FLAG_NORMAL,
  1057. SERVICE_SERVER)
  1058. //
  1059. // Call downlevel server.
  1060. //
  1061. apiStatus = RxNetShareCheck(servername, device, type);
  1062. NET_REMOTE_END
  1063. return(apiStatus);
  1064. } // NetShareCheck
  1065. NET_API_STATUS NET_API_FUNCTION
  1066. NetShareDel (
  1067. IN LPTSTR servername,
  1068. IN LPTSTR netname,
  1069. IN DWORD reserved
  1070. )
  1071. /*++
  1072. Routine Description:
  1073. This is the DLL entrypoint for NetShareDel.
  1074. Arguments:
  1075. servername --A pointer to an ASCIIZ string containing the name of
  1076. the remote server on which the function is to execute. A NULL
  1077. pointer or string specifies the local machine.
  1078. netname --A pointer to an ASCIIZ string containing the netname of
  1079. the share to delete.
  1080. reserved --Reserved, must be zero.
  1081. Return Value:
  1082. --*/
  1083. {
  1084. NET_API_STATUS apiStatus;
  1085. BOOL committingIpcDelete = FALSE;
  1086. SHARE_DEL_HANDLE handle;
  1087. BOOL tryDownLevel = FALSE;
  1088. if ( !netname || (*netname == 0) || reserved ) {
  1089. return ERROR_INVALID_PARAMETER;
  1090. }
  1091. RpcTryExcept {
  1092. if ( STRICMP( netname, TEXT("IPC$") ) != 0 ) {
  1093. apiStatus = NetrShareDel(
  1094. servername,
  1095. netname,
  1096. reserved
  1097. );
  1098. } else {
  1099. apiStatus = NetrShareDelStart(
  1100. servername,
  1101. netname,
  1102. reserved,
  1103. &handle
  1104. );
  1105. if ( apiStatus == NERR_Success ) {
  1106. committingIpcDelete = TRUE;
  1107. apiStatus = NetrShareDelCommit( &handle );
  1108. }
  1109. }
  1110. } RpcExcept ( 1 ) {
  1111. RPC_STATUS rpcStatus;
  1112. rpcStatus = RpcExceptionCode( );
  1113. if ( committingIpcDelete && (rpcStatus == RPC_S_CALL_FAILED) ) {
  1114. apiStatus = NERR_Success;
  1115. } else {
  1116. apiStatus = NetpHandleRpcFailure(
  1117. "NetShareDel",
  1118. rpcStatus,
  1119. servername,
  1120. SERVICE_SERVER,
  1121. NET_REMOTE_FLAG_NORMAL,
  1122. &tryDownLevel
  1123. );
  1124. }
  1125. }
  1126. RpcEndExcept
  1127. if (apiStatus == NERR_TryDownLevel) {
  1128. tryDownLevel = TRUE;
  1129. }
  1130. if ( tryDownLevel ) {
  1131. //
  1132. // Call downlevel server.
  1133. //
  1134. // note: push value 0 instead of real reserved
  1135. //
  1136. apiStatus = RxNetShareDel(servername, netname, 0);
  1137. }
  1138. return apiStatus;
  1139. } // NetShareDel
  1140. NET_API_STATUS NET_API_FUNCTION
  1141. NetShareDelSticky (
  1142. IN LPTSTR servername,
  1143. IN LPTSTR netname,
  1144. IN DWORD reserved
  1145. )
  1146. /*++
  1147. Routine Description:
  1148. This is the DLL entrypoint for NetShareDelSticky.
  1149. Arguments:
  1150. servername --A pointer to an ASCIIZ string containing the name of
  1151. the remote server on which the function is to execute. A NULL
  1152. pointer or string specifies the local machine.
  1153. netname --A pointer to an ASCIIZ string containing the netname of
  1154. the share to delete.
  1155. reserved --Reserved, must be zero.
  1156. Return Value:
  1157. --*/
  1158. {
  1159. NET_API_STATUS apiStatus;
  1160. if (!(netname && *netname) || reserved) {
  1161. return ERROR_INVALID_PARAMETER;
  1162. }
  1163. NET_REMOTE_TRY_RPC
  1164. apiStatus = NetrShareDelSticky (
  1165. servername,
  1166. netname,
  1167. reserved);
  1168. NET_REMOTE_RPC_FAILED(
  1169. "NetShareDelSticky",
  1170. servername,
  1171. apiStatus,
  1172. NET_REMOTE_FLAG_NORMAL,
  1173. SERVICE_SERVER)
  1174. //
  1175. // No downlevel call.
  1176. //
  1177. apiStatus = ERROR_NOT_SUPPORTED;
  1178. NET_REMOTE_END
  1179. return(apiStatus);
  1180. } // NetShareDelSticky
  1181. NET_API_STATUS NET_API_FUNCTION
  1182. NetShareEnum (
  1183. IN LPTSTR servername,
  1184. IN DWORD level,
  1185. OUT LPBYTE *bufptr,
  1186. IN DWORD prefmaxlen,
  1187. OUT LPDWORD entriesread,
  1188. OUT LPDWORD totalentries,
  1189. IN OUT LPDWORD resume_handle
  1190. )
  1191. /*++
  1192. Routine Description:
  1193. This is the DLL entrypoint for NetShareEnum
  1194. Arguments:
  1195. servername --A pointer to an ASCIIZ string containing the name of
  1196. the remote server on which the function is to execute. A NULL
  1197. pointer or string specifies the local machine.
  1198. level --Level of information required. 0, 1 and 2 are valid.
  1199. bufptr --On return a pointer to the return information structure
  1200. is returned in the address pointed to by bufptr.
  1201. prefmaxlen --Prefered maximum length of returned data (in 8-bit
  1202. bytes). 0xffffffff specifies no limit.
  1203. entriesread --On return the actual enumerated element count is
  1204. located in the DWORD pointed to by entriesread.
  1205. totalentries --On return the total entries available to be
  1206. enumerated is located in the DWORD pointed to by
  1207. totalentries.
  1208. resumehandle --On return, a resume handle is stored in the DWORD
  1209. pointed to by resumehandle, and is used to continue an
  1210. existing share search. The handle should be zero on the first
  1211. call and left unchanged for subsequent calls. If resumehandle
  1212. is NULL, then no resume handle is stored..
  1213. Return Value:
  1214. --*/
  1215. {
  1216. NET_API_STATUS apiStatus;
  1217. GENERIC_INFO_CONTAINER genericInfoContainer;
  1218. GENERIC_ENUM_STRUCT infoStruct;
  1219. //
  1220. // check the caller's parameters
  1221. //
  1222. *totalentries = *entriesread = 0;
  1223. *bufptr = NULL;
  1224. if ( (level > 2) && (level != 501) && (level != 502) ) {
  1225. return ERROR_INVALID_LEVEL;
  1226. }
  1227. genericInfoContainer.Buffer = NULL;
  1228. genericInfoContainer.EntriesRead = 0;
  1229. infoStruct.Container = &genericInfoContainer;
  1230. infoStruct.Level = level;
  1231. NET_REMOTE_TRY_RPC
  1232. apiStatus = NetrShareEnum (
  1233. servername,
  1234. (LPSHARE_ENUM_STRUCT) &infoStruct,
  1235. prefmaxlen,
  1236. totalentries,
  1237. resume_handle);
  1238. if (genericInfoContainer.Buffer != NULL) {
  1239. *bufptr = (LPBYTE)genericInfoContainer.Buffer;
  1240. *entriesread = genericInfoContainer.EntriesRead;
  1241. } else {
  1242. *bufptr = NULL;
  1243. *entriesread = 0;
  1244. }
  1245. NET_REMOTE_RPC_FAILED(
  1246. "NetShareEnum",
  1247. servername,
  1248. apiStatus,
  1249. NET_REMOTE_FLAG_NORMAL,
  1250. SERVICE_SERVER)
  1251. //
  1252. // Call downlevel server.
  1253. //
  1254. if ( level != 502 && level != 501 ) {
  1255. apiStatus = RxNetShareEnum(servername, level, bufptr,
  1256. prefmaxlen, entriesread, totalentries, resume_handle);
  1257. } else {
  1258. apiStatus = ERROR_NOT_SUPPORTED;
  1259. }
  1260. NET_REMOTE_END
  1261. //
  1262. // If we haven't gotten anything, and the server is offline,
  1263. // return the offline share state
  1264. //
  1265. if( ( *bufptr == NULL || *entriesread == 0 ) &&
  1266. ARGUMENT_PRESENT( servername ) &&
  1267. CSCIsServerOffline( servername ) ) {
  1268. NET_API_STATUS cscStatus;
  1269. cscStatus = CSCNetShareEnum(
  1270. servername,
  1271. level,
  1272. bufptr,
  1273. entriesread,
  1274. totalentries
  1275. );
  1276. if( cscStatus == NERR_Success ) {
  1277. apiStatus = cscStatus;
  1278. }
  1279. }
  1280. return(apiStatus);
  1281. } // NetShareEnum
  1282. NET_API_STATUS NET_API_FUNCTION
  1283. NetShareEnumSticky (
  1284. IN LPTSTR servername,
  1285. IN DWORD level,
  1286. OUT LPBYTE *bufptr,
  1287. IN DWORD prefmaxlen,
  1288. OUT LPDWORD entriesread,
  1289. OUT LPDWORD totalentries,
  1290. IN OUT LPDWORD resume_handle
  1291. )
  1292. /*++
  1293. Routine Description:
  1294. This is the DLL entrypoint for NetShareEnumSticky
  1295. Arguments:
  1296. servername --A pointer to an ASCIIZ string containing the name of
  1297. the remote server on which the function is to execute. A NULL
  1298. pointer or string specifies the local machine.
  1299. level --Level of information required. 0, 1 and 2 are valid.
  1300. bufptr --On return a pointer to the return information structure
  1301. is returned in the address pointed to by bufptr.
  1302. prefmaxlen --Prefered maximum length of returned data (in 8-bit
  1303. bytes). 0xffffffff specifies no limit.
  1304. entriesread --On return the actual enumerated element count is
  1305. located in the DWORD pointed to by entriesread.
  1306. totalentries --On return the total entries available to be
  1307. enumerated is located in the DWORD pointed to by
  1308. totalentries.
  1309. resumehandle --On return, a resume handle is stored in the DWORD
  1310. pointed to by resumehandle, and is used to continue an
  1311. existing share search. The handle should be zero on the first
  1312. call and left unchanged for subsequent calls. If resumehandle
  1313. is NULL, then no resume handle is stored..
  1314. Return Value:
  1315. --*/
  1316. {
  1317. NET_API_STATUS apiStatus;
  1318. GENERIC_INFO_CONTAINER genericInfoContainer;
  1319. GENERIC_ENUM_STRUCT infoStruct;
  1320. //
  1321. // check the caller's parameters
  1322. //
  1323. *totalentries = *entriesread = 0;
  1324. *bufptr = NULL;
  1325. if ( (level > 2) && (level != 501) && (level != 502) ) {
  1326. return ERROR_INVALID_LEVEL;
  1327. }
  1328. genericInfoContainer.Buffer = NULL;
  1329. genericInfoContainer.EntriesRead = 0;
  1330. infoStruct.Container = &genericInfoContainer;
  1331. infoStruct.Level = level;
  1332. NET_REMOTE_TRY_RPC
  1333. apiStatus = NetrShareEnumSticky (
  1334. servername,
  1335. (LPSHARE_ENUM_STRUCT) &infoStruct,
  1336. prefmaxlen,
  1337. totalentries,
  1338. resume_handle);
  1339. if (genericInfoContainer.Buffer != NULL) {
  1340. *bufptr = (LPBYTE)genericInfoContainer.Buffer;
  1341. *entriesread = genericInfoContainer.EntriesRead;
  1342. } else {
  1343. *bufptr = NULL;
  1344. *entriesread = 0;
  1345. }
  1346. NET_REMOTE_RPC_FAILED(
  1347. "NetShareEnum",
  1348. servername,
  1349. apiStatus,
  1350. NET_REMOTE_FLAG_NORMAL,
  1351. SERVICE_SERVER)
  1352. //
  1353. // No downlevel support
  1354. //
  1355. apiStatus = ERROR_NOT_SUPPORTED;
  1356. NET_REMOTE_END
  1357. return(apiStatus);
  1358. } // NetShareEnumSticky
  1359. NET_API_STATUS NET_API_FUNCTION
  1360. NetShareGetInfo (
  1361. IN LPTSTR servername,
  1362. IN LPTSTR netname,
  1363. IN DWORD level,
  1364. OUT LPBYTE *bufptr
  1365. )
  1366. /*++
  1367. Routine Description:
  1368. NetShareGetInfo
  1369. Arguments:
  1370. servername --A pointer to an ASCIIZ string containing the name of
  1371. the remote server on which the function is to execute. A NULL
  1372. pointer or string specifies the local machine.
  1373. netname --A pointer to an ASCIIZ string containing the netname of
  1374. the share to return information on.
  1375. level --Level of information required. 0, 1 and 2 are valid.
  1376. bufptr --On return a pointer to the return information structure
  1377. is returned in the address pointed to by bufptr.
  1378. Return Value:
  1379. --*/
  1380. {
  1381. NET_API_STATUS apiStatus;
  1382. if (bufptr == NULL) {
  1383. return ERROR_INVALID_PARAMETER;
  1384. }
  1385. *bufptr = NULL; // Must be NULL so RPC knows to fill it in.
  1386. if ( (level > 2) &&
  1387. (level != 501) &&
  1388. (level != 502) &&
  1389. (level != 1005) ) {
  1390. return ERROR_INVALID_LEVEL;
  1391. }
  1392. if (!(netname && *netname)) {
  1393. return ERROR_INVALID_PARAMETER;
  1394. }
  1395. NET_REMOTE_TRY_RPC
  1396. apiStatus = NetrShareGetInfo (
  1397. servername,
  1398. netname,
  1399. level,
  1400. (LPSHARE_INFO) bufptr);
  1401. NET_REMOTE_RPC_FAILED(
  1402. "NetShareGetInfo",
  1403. servername,
  1404. apiStatus,
  1405. NET_REMOTE_FLAG_NORMAL,
  1406. SERVICE_SERVER)
  1407. //
  1408. // Call downlevel server.
  1409. //
  1410. if( level == 0 || level == 1 || level == 2 ) {
  1411. apiStatus = RxNetShareGetInfo(servername, netname, level, bufptr);
  1412. } else {
  1413. apiStatus = ERROR_NOT_SUPPORTED;
  1414. }
  1415. NET_REMOTE_END
  1416. if( *bufptr == NULL &&
  1417. ARGUMENT_PRESENT( servername ) &&
  1418. ARGUMENT_PRESENT( netname ) &&
  1419. CSCIsServerOffline( servername) ) {
  1420. NET_API_STATUS cscStatus;
  1421. cscStatus = CSCNetShareGetInfo ( servername, netname, level, bufptr );
  1422. if( cscStatus == NERR_Success ) {
  1423. apiStatus = cscStatus;
  1424. }
  1425. }
  1426. return(apiStatus);
  1427. } // NetShareGetInfo
  1428. NET_API_STATUS NET_API_FUNCTION
  1429. NetShareSetInfo (
  1430. IN LPTSTR servername,
  1431. IN LPTSTR netname,
  1432. IN DWORD level,
  1433. IN LPBYTE buf,
  1434. OUT LPDWORD parm_err
  1435. )
  1436. /*++
  1437. Routine Description:
  1438. This is the DLL entrypoint for NetShareSetInfo
  1439. Arguments:
  1440. servername --A pointer to an ASCIIZ string containing the name of
  1441. the remote server on which the function is to execute. A NULL
  1442. pointer or string specifies the local machine.
  1443. netname --A pointer to an ASCIIZ string containing the netname of
  1444. the share to set information on.
  1445. level --Level of information to set.
  1446. buf --A pointer to a buffer containing the share information. If
  1447. parmnum is non zero then the buffer contains only the
  1448. appropriate data for the specific element.
  1449. parm_err --Optional pointer to a DWORD to return the index of the
  1450. first parameter in error when ERROR_INVALID_PARAMETER is
  1451. returned. If NULL the parameter is not returned on error.
  1452. Return Value:
  1453. --*/
  1454. {
  1455. NET_API_STATUS apiStatus;
  1456. NTSTATUS status;
  1457. ULONG sdLength = 0;
  1458. ULONG oldSdLength;
  1459. PSECURITY_DESCRIPTOR securityDescriptor = NULL;
  1460. PSECURITY_DESCRIPTOR oldSecurityDescriptor = NULL;
  1461. LPSHARE_INFO_1501 shi1501 = NULL;
  1462. NET_REMOTE_TRY_RPC
  1463. //
  1464. // If the info level can change the security descriptor, get
  1465. // the necessary information.
  1466. //
  1467. // *** Note that this code expects the layout of the reserved
  1468. // and security_descriptor fields in the 502 struct to
  1469. // match the 1501 struct.
  1470. //
  1471. if ( level == 502 ) {
  1472. if (buf == NULL) {
  1473. SET_ERROR_PARAMETER(PARM_ERROR_UNKNOWN);
  1474. return ERROR_INVALID_PARAMETER;
  1475. }
  1476. shi1501 =
  1477. (LPSHARE_INFO_1501)&((LPSHARE_INFO_502)buf)->shi502_reserved;
  1478. } else if ( level == SHARE_FILE_SD_INFOLEVEL ) {
  1479. shi1501 = (LPSHARE_INFO_1501)buf;
  1480. }
  1481. if ( shi1501 != NULL ) {
  1482. oldSdLength = shi1501->shi1501_reserved;
  1483. oldSecurityDescriptor = shi1501->shi1501_security_descriptor;
  1484. if ( oldSecurityDescriptor != NULL ) {
  1485. //
  1486. // Make a self relative security descriptor for use in the
  1487. // RPC call.
  1488. //
  1489. if ( !RtlValidSecurityDescriptor( oldSecurityDescriptor) ) {
  1490. SET_ERROR_PARAMETER( SHARE_FILE_SD_PARMNUM );
  1491. return ERROR_INVALID_PARAMETER;
  1492. }
  1493. status = RtlMakeSelfRelativeSD(
  1494. oldSecurityDescriptor,
  1495. NULL,
  1496. &sdLength
  1497. );
  1498. if ( status != STATUS_BUFFER_TOO_SMALL ) {
  1499. SET_ERROR_PARAMETER( SHARE_FILE_SD_PARMNUM );
  1500. return ERROR_INVALID_PARAMETER;
  1501. } else {
  1502. securityDescriptor = MIDL_user_allocate( sdLength );
  1503. if ( securityDescriptor == NULL) {
  1504. return ERROR_NOT_ENOUGH_MEMORY;
  1505. } else {
  1506. //
  1507. // Make an appropriate self-relative security
  1508. // descriptor.
  1509. //
  1510. status = RtlMakeSelfRelativeSD(
  1511. oldSecurityDescriptor,
  1512. securityDescriptor,
  1513. &sdLength
  1514. );
  1515. if ( !NT_SUCCESS(status) ) {
  1516. MIDL_user_free( securityDescriptor );
  1517. SET_ERROR_PARAMETER( SHARE_FILE_SD_PARMNUM );
  1518. return ERROR_INVALID_PARAMETER;
  1519. }
  1520. shi1501->shi1501_reserved = sdLength;
  1521. shi1501->shi1501_security_descriptor =
  1522. securityDescriptor;
  1523. }
  1524. }
  1525. } else {
  1526. shi1501->shi1501_reserved = 0;
  1527. }
  1528. }
  1529. apiStatus = NetrShareSetInfo(
  1530. servername,
  1531. netname,
  1532. level,
  1533. (LPSHARE_INFO) &buf,
  1534. parm_err);
  1535. if ( shi1501 != NULL ) {
  1536. //
  1537. // restore old values
  1538. //
  1539. shi1501->shi1501_reserved = oldSdLength;
  1540. shi1501->shi1501_security_descriptor = oldSecurityDescriptor;
  1541. MIDL_user_free( securityDescriptor );
  1542. }
  1543. NET_REMOTE_RPC_FAILED(
  1544. "NetShareSetInfo",
  1545. servername,
  1546. apiStatus,
  1547. NET_REMOTE_FLAG_NORMAL,
  1548. SERVICE_SERVER)
  1549. //
  1550. // Call downlevel server.
  1551. //
  1552. if ( level != 502 &&
  1553. level != 501 &&
  1554. level != SHARE_FILE_SD_INFOLEVEL &&
  1555. level != 1005 ) {
  1556. apiStatus = RxNetShareSetInfo(
  1557. servername,
  1558. netname,
  1559. level,
  1560. buf,
  1561. parm_err);
  1562. } else {
  1563. apiStatus = ERROR_NOT_SUPPORTED;
  1564. }
  1565. NET_REMOTE_END
  1566. return(apiStatus);
  1567. } // NetShareSetInfo
  1568. NET_API_STATUS NET_API_FUNCTION
  1569. NetServerDiskEnum (
  1570. IN LPTSTR servername,
  1571. IN DWORD level,
  1572. OUT LPBYTE *bufptr,
  1573. IN DWORD prefmaxlen,
  1574. OUT LPDWORD entriesread,
  1575. OUT LPDWORD totalentries,
  1576. IN OUT LPDWORD resume_handle
  1577. )
  1578. /*++
  1579. Routine Description:
  1580. This is the DLL entrypoint for NetServerDiskEnum.
  1581. Arguments:
  1582. servername --A pointer to an ASCIIZ string containing the name of
  1583. the remote server on which the function is to execute. A NULL
  1584. pointer or string specifies the local machine.
  1585. level --Level of information required. 0 is the only valid level.
  1586. bufptr --On return a pointer to the return information structure
  1587. is returned in the address pointed to by bufptr.
  1588. prefmaxlen --Prefered maximum length of returned data (in 8-bit
  1589. bytes). 0xffffffff specifies no limit.
  1590. entriesread --On return the actual enumerated element count is
  1591. located in the DWORD pointed to by entriesread.
  1592. totalentries --On return the total entries available to be
  1593. enumerated is located in the DWORD pointed to by totalentries
  1594. resumehandle --On return, a resume handle is stored in the DWORD
  1595. pointed to by resumehandle, and is used to continue an
  1596. existing server disk search. The handle should be zero on the
  1597. first call and left unchanged for subsequent calls. If
  1598. resumehandle is NULL, then no resume handle is stored..
  1599. Return Value:
  1600. --*/
  1601. {
  1602. NET_API_STATUS apiStatus;
  1603. DISK_ENUM_CONTAINER diskEnumContainer;
  1604. diskEnumContainer.Buffer = NULL;
  1605. NET_REMOTE_TRY_RPC
  1606. apiStatus = NetrServerDiskEnum (
  1607. servername,
  1608. level,
  1609. &diskEnumContainer,
  1610. prefmaxlen,
  1611. totalentries,
  1612. resume_handle);
  1613. if (diskEnumContainer.Buffer != NULL) {
  1614. *bufptr = (LPBYTE)diskEnumContainer.Buffer;
  1615. } else {
  1616. *bufptr = NULL;
  1617. }
  1618. if (diskEnumContainer.EntriesRead > 0) {
  1619. //
  1620. // We must subtract out the extra count that we added so
  1621. // that RPC would buffer the extra NUL at the end of the list.
  1622. //
  1623. *entriesread = diskEnumContainer.EntriesRead - 1;
  1624. } else {
  1625. *entriesread = 0;
  1626. }
  1627. NET_REMOTE_RPC_FAILED(
  1628. "NetServerDiskEnum",
  1629. servername,
  1630. apiStatus,
  1631. NET_REMOTE_FLAG_NORMAL,
  1632. SERVICE_SERVER)
  1633. //
  1634. // Call downlevel version of the API.
  1635. //
  1636. apiStatus = RxNetServerDiskEnum(
  1637. servername,
  1638. level,
  1639. bufptr,
  1640. prefmaxlen,
  1641. entriesread,
  1642. totalentries,
  1643. resume_handle);
  1644. NET_REMOTE_END
  1645. return(apiStatus);
  1646. } // NetServerDiskEnum
  1647. NET_API_STATUS NET_API_FUNCTION
  1648. NetServerGetInfo (
  1649. IN LPTSTR servername,
  1650. IN DWORD level,
  1651. OUT LPBYTE *bufptr
  1652. )
  1653. /*++
  1654. Routine Description:
  1655. This is the DLL entrypoint for NetServerGetInfo
  1656. Arguments:
  1657. servername --A pointer to an ASCIIZ string containing the name of
  1658. the remote server on which the function is to execute. A NULL
  1659. pointer or string specifies the local machine.
  1660. level --Level of information required. 100, 101 and 102 are valid
  1661. for all platforms. 302, 402, 403, 502 are valid for the
  1662. appropriate platform.
  1663. bufptr --On return a pointer to the return information structure
  1664. is returned in the address pointed to by bufptr.
  1665. Return Value:
  1666. --*/
  1667. {
  1668. NET_API_STATUS apiStatus;
  1669. *bufptr = NULL; // Must be NULL so RPC knows to fill it in.
  1670. NET_REMOTE_TRY_RPC
  1671. apiStatus = NetrServerGetInfo (
  1672. servername,
  1673. level,
  1674. (LPSERVER_INFO) bufptr);
  1675. NET_REMOTE_RPC_FAILED(
  1676. "NetServerGetInfo",
  1677. servername,
  1678. apiStatus,
  1679. NET_REMOTE_FLAG_NORMAL,
  1680. SERVICE_SERVER)
  1681. //
  1682. // Call downlevel version of the API.
  1683. //
  1684. apiStatus = RxNetServerGetInfo (
  1685. servername,
  1686. level,
  1687. bufptr);
  1688. NET_REMOTE_END
  1689. return(apiStatus);
  1690. } // NetServerGetInfo
  1691. NET_API_STATUS NET_API_FUNCTION
  1692. NetServerSetInfo (
  1693. IN LPTSTR servername,
  1694. IN DWORD level,
  1695. IN LPBYTE buf,
  1696. OUT LPDWORD parm_err
  1697. )
  1698. /*++
  1699. Routine Description:
  1700. This is the DLL entrypoint for NetServerSetInfo.
  1701. Arguments:
  1702. servername --A pointer to an ASCIIZ string containing the name of
  1703. the remote server on which the function is to execute. A NULL
  1704. pointer or string specifies the local machine.
  1705. level --Level of information to set.
  1706. buf --A pointer to a buffer containing the server information. If
  1707. parmnum is non zero then the buffer contains only the
  1708. appropriate data for the specific element.
  1709. parm_err --Optional pointer to a DWORD to return the index of the
  1710. first parameter in error when ERROR_INVALID_PARAMETER is
  1711. returned. If NULL the parameter is not returned on error.
  1712. Return Value:
  1713. --*/
  1714. {
  1715. NET_API_STATUS apiStatus;
  1716. NET_REMOTE_TRY_RPC
  1717. apiStatus = NetrServerSetInfo (
  1718. servername,
  1719. level,
  1720. (LPSERVER_INFO ) &buf,
  1721. parm_err);
  1722. NET_REMOTE_RPC_FAILED(
  1723. "NetServerSetInfo",
  1724. servername,
  1725. apiStatus,
  1726. NET_REMOTE_FLAG_NORMAL,
  1727. SERVICE_SERVER)
  1728. //
  1729. // Call downlevel server.
  1730. //
  1731. apiStatus = RxNetServerSetInfo(
  1732. servername,
  1733. level,
  1734. buf,
  1735. parm_err);
  1736. NET_REMOTE_END
  1737. return(apiStatus);
  1738. } // NetServerSetInfo
  1739. NET_API_STATUS NET_API_FUNCTION
  1740. NetServerStatisticsGet (
  1741. IN LPTSTR servername,
  1742. IN DWORD level,
  1743. IN DWORD options,
  1744. OUT LPBYTE *bufptr
  1745. )
  1746. /*++
  1747. Routine Description:
  1748. This is the DLL entrypoint for NetStatisticsGet.
  1749. Arguments:
  1750. servername --Points to an ASCIIZ string that contains the name of the
  1751. server on which to execute NetStatisticsGet. A NULL pointer or
  1752. NULL string specifies the local computer.
  1753. level --Specifies the level of detail requested; must be 0.
  1754. options --Specifies the options flags.
  1755. Bit(s) Meaning
  1756. 0 Clear statistics.
  1757. 1-31 Reserved; must be 0.
  1758. bufptr --On return a pointer to the returned information is
  1759. returned in the address pointed to by bufptr.
  1760. Return Value:
  1761. --*/
  1762. {
  1763. NET_API_STATUS apiStatus;
  1764. *bufptr = NULL; // Must be NULL so RPC knows to fill it in.
  1765. NET_REMOTE_TRY_RPC
  1766. apiStatus = NetrServerStatisticsGet (
  1767. servername,
  1768. SERVICE_SERVER,
  1769. level,
  1770. options,
  1771. (LPSTAT_SERVER_0 *) bufptr);
  1772. NET_REMOTE_RPC_FAILED(
  1773. "NetServerStatisticsGet",
  1774. servername,
  1775. apiStatus,
  1776. NET_REMOTE_FLAG_NORMAL,
  1777. SERVICE_SERVER)
  1778. //
  1779. // RPC call didn't work - try down-level routine
  1780. //
  1781. apiStatus = RxNetStatisticsGet(
  1782. servername,
  1783. SERVICE_SERVER,
  1784. level,
  1785. options,
  1786. bufptr
  1787. );
  1788. NET_REMOTE_END
  1789. return(apiStatus);
  1790. } // NetServerStatisticsGet
  1791. NET_API_STATUS NET_API_FUNCTION
  1792. NetServerTransportAdd (
  1793. IN LPTSTR servername,
  1794. IN DWORD level,
  1795. IN LPBYTE bufptr
  1796. )
  1797. /*++
  1798. Routine Description:
  1799. This is the DLL entrypoint for NetServerTransportAdd
  1800. Arguments:
  1801. Return Value:
  1802. --*/
  1803. {
  1804. NET_API_STATUS apiStatus;
  1805. NET_REMOTE_TRY_RPC
  1806. apiStatus = NetrServerTransportAdd (
  1807. servername,
  1808. level,
  1809. (LPSERVER_TRANSPORT_INFO_0) bufptr);
  1810. NET_REMOTE_RPC_FAILED(
  1811. "NetServerTransportAdd",
  1812. servername,
  1813. apiStatus,
  1814. NET_REMOTE_FLAG_NORMAL,
  1815. SERVICE_SERVER)
  1816. //
  1817. // No downlevel call.
  1818. //
  1819. apiStatus = ERROR_NOT_SUPPORTED;
  1820. NET_REMOTE_END
  1821. return(apiStatus);
  1822. } // NetServerTransportAdd
  1823. NET_API_STATUS NET_API_FUNCTION
  1824. NetServerTransportDelEx (
  1825. IN LPTSTR servername,
  1826. IN DWORD level,
  1827. IN LPBYTE bufptr
  1828. )
  1829. /*++
  1830. Routine Description:
  1831. This is the DLL entrypoint for NetServerTransportAdd
  1832. Arguments:
  1833. Return Value:
  1834. --*/
  1835. {
  1836. NET_API_STATUS apiStatus;
  1837. NET_REMOTE_TRY_RPC
  1838. apiStatus = NetrServerTransportDelEx (
  1839. servername,
  1840. level,
  1841. (LPTRANSPORT_INFO) bufptr);
  1842. NET_REMOTE_RPC_FAILED(
  1843. "NetServerTransportDel",
  1844. servername,
  1845. apiStatus,
  1846. NET_REMOTE_FLAG_NORMAL,
  1847. SERVICE_SERVER)
  1848. //
  1849. // No downlevel call.
  1850. //
  1851. apiStatus = ERROR_NOT_SUPPORTED;
  1852. NET_REMOTE_END
  1853. // Around the Win2K/NT4 time frame a bug was introduced for TransportDel with
  1854. // level other than 0. In these cases, the buffer was cast instead of marshalled
  1855. // correctly over RPC. This means that Level 1 never worked anyway. To fix this,
  1856. // we added a new RPC interface that supports all the other levels. However, downlevel
  1857. // servers will not support this interface. In these cases, we call back with the TRUE
  1858. // level 0 interface to satisfy backwards compatibility
  1859. if( apiStatus == RPC_S_PROCNUM_OUT_OF_RANGE )
  1860. {
  1861. apiStatus = NetServerTransportDel( servername, 0, bufptr );
  1862. }
  1863. return(apiStatus);
  1864. } // NetServerTransportDel
  1865. NET_API_STATUS NET_API_FUNCTION
  1866. NetServerTransportDel (
  1867. IN LPTSTR servername,
  1868. IN DWORD level,
  1869. IN LPBYTE bufptr
  1870. )
  1871. /*++
  1872. Routine Description:
  1873. This is the DLL entrypoint for NetServerTransportAdd
  1874. Arguments:
  1875. Return Value:
  1876. --*/
  1877. {
  1878. NET_API_STATUS apiStatus;
  1879. if( level == 0 )
  1880. {
  1881. NET_REMOTE_TRY_RPC
  1882. apiStatus = NetrServerTransportDel (
  1883. servername,
  1884. level,
  1885. (LPSERVER_TRANSPORT_INFO_0) bufptr);
  1886. NET_REMOTE_RPC_FAILED(
  1887. "NetServerTransportDel",
  1888. servername,
  1889. apiStatus,
  1890. NET_REMOTE_FLAG_NORMAL,
  1891. SERVICE_SERVER)
  1892. //
  1893. // No downlevel call.
  1894. //
  1895. apiStatus = ERROR_NOT_SUPPORTED;
  1896. NET_REMOTE_END
  1897. }
  1898. else
  1899. {
  1900. // If they want level 1, we need to use the new RPC interface. See
  1901. // the comment in the TransportDelEx code above
  1902. apiStatus = NetServerTransportDelEx( servername, level, bufptr );
  1903. }
  1904. return(apiStatus);
  1905. } // NetServerTransportDel
  1906. NET_API_STATUS NET_API_FUNCTION
  1907. NetServerTransportEnum (
  1908. IN LPTSTR servername,
  1909. IN DWORD level,
  1910. OUT LPBYTE *bufptr,
  1911. IN DWORD prefmaxlen,
  1912. OUT LPDWORD entriesread,
  1913. OUT LPDWORD totalentries,
  1914. IN OUT LPDWORD resume_handle
  1915. )
  1916. /*++
  1917. Routine Description:
  1918. This is the DLL entrypoint for NetServerTransportEnum
  1919. Arguments:
  1920. Return Value:
  1921. --*/
  1922. {
  1923. NET_API_STATUS apiStatus;
  1924. GENERIC_INFO_CONTAINER genericInfoContainer;
  1925. GENERIC_ENUM_STRUCT infoStruct;
  1926. genericInfoContainer.Buffer = NULL;
  1927. genericInfoContainer.EntriesRead = 0;
  1928. infoStruct.Container = &genericInfoContainer;
  1929. infoStruct.Level = level;
  1930. NET_REMOTE_TRY_RPC
  1931. apiStatus = NetrServerTransportEnum (
  1932. servername,
  1933. (LPSERVER_XPORT_ENUM_STRUCT) &infoStruct,
  1934. prefmaxlen,
  1935. totalentries,
  1936. resume_handle);
  1937. if (genericInfoContainer.Buffer != NULL) {
  1938. *bufptr = (LPBYTE)genericInfoContainer.Buffer;
  1939. *entriesread = genericInfoContainer.EntriesRead;
  1940. } else {
  1941. *bufptr = NULL;
  1942. *entriesread = 0;
  1943. }
  1944. NET_REMOTE_RPC_FAILED(
  1945. "NetServerTransportEnum",
  1946. servername,
  1947. apiStatus,
  1948. NET_REMOTE_FLAG_NORMAL,
  1949. SERVICE_SERVER)
  1950. //
  1951. // No downlevel call.
  1952. //
  1953. apiStatus = ERROR_NOT_SUPPORTED;
  1954. NET_REMOTE_END
  1955. return(apiStatus);
  1956. } // NetServerTransportEnum
  1957. NET_API_STATUS NET_API_FUNCTION
  1958. NetRemoteTOD (
  1959. IN LPCWSTR servername,
  1960. OUT LPBYTE *bufptr
  1961. )
  1962. /*++
  1963. Routine Description:
  1964. This is the DLL entrypoint for NetRemoteTOD
  1965. Arguments:
  1966. servername - name of the server on which the API so to be executed.
  1967. bufptr - the location where the address of the buffer allocated
  1968. for the time-of-day information is placed.
  1969. Return Value:
  1970. NERR_SUCCESS if there was no error. Otherwise, the error code is
  1971. returned.
  1972. --*/
  1973. {
  1974. NET_API_STATUS apiStatus;
  1975. //
  1976. // Call API
  1977. //
  1978. *bufptr = NULL; // Must be NULL so RPC knows to fill it in.
  1979. NET_REMOTE_TRY_RPC
  1980. apiStatus = NetrRemoteTOD (
  1981. (LPWSTR)servername,
  1982. (TIME_OF_DAY_INFO **) bufptr);
  1983. NET_REMOTE_RPC_FAILED(
  1984. "NetRemoteTOD",
  1985. servername,
  1986. apiStatus,
  1987. NET_REMOTE_FLAG_NORMAL,
  1988. SERVICE_TIMESOURCE )
  1989. apiStatus = RxNetRemoteTOD (
  1990. (LPWSTR)servername,
  1991. (LPBYTE *) bufptr);
  1992. NET_REMOTE_END
  1993. return(apiStatus);
  1994. }
  1995. NET_API_STATUS
  1996. I_NetServerSetServiceBitsEx (
  1997. IN LPWSTR ServerName,
  1998. IN LPWSTR EmulatedServerName OPTIONAL,
  1999. IN LPTSTR TransportName OPTIONAL,
  2000. IN DWORD ServiceBitsOfInterest,
  2001. IN DWORD ServiceBits,
  2002. IN DWORD UpdateImmediately
  2003. )
  2004. /*++
  2005. Routine Description:
  2006. This is the DLL entrypoint for I_NetServerSetServiceBitsEx. This
  2007. routine sets the value of the Server Type as sent in server
  2008. announcement messages. It is an internal API used only by the
  2009. service controller.
  2010. Arguments:
  2011. ServerName - Used by RPC to direct the call. This API may only be
  2012. issued locally. This is enforced by the client stub.
  2013. EmulatedServerName - the name server using for accepting connections
  2014. on the network and for announcements. If null, use the priamary
  2015. server name.
  2016. TransportName - the name of one of the transports the server is bound
  2017. on. If null, set the bits for all the transports.
  2018. ServiceBitsOfInterest - a mask indicating which bits are significant
  2019. in 'ServiceBits'
  2020. ServiceBits - Bits (preassigned to various components by Microsoft)
  2021. indicating which services are active. This field is not
  2022. interpreted by the server service.
  2023. Return Value:
  2024. NET_API_STATUS - NO_ERROR or ERROR_NOT_SUPPORTED.
  2025. --*/
  2026. {
  2027. NET_API_STATUS apiStatus;
  2028. DWORD localOrRemote;
  2029. //
  2030. // Don't let this API go remote.
  2031. //
  2032. if ((ServerName != NULL) && (*ServerName != '\0')) {
  2033. apiStatus = NetpIsRemote(ServerName, &localOrRemote, NULL, 0);
  2034. if (apiStatus != NERR_Success) {
  2035. return apiStatus;
  2036. }
  2037. if (localOrRemote == ISREMOTE) {
  2038. return ERROR_NOT_SUPPORTED;
  2039. }
  2040. }
  2041. //
  2042. // Do the call.
  2043. //
  2044. NET_REMOTE_TRY_RPC
  2045. apiStatus = I_NetrServerSetServiceBitsEx (
  2046. ServerName,
  2047. EmulatedServerName,
  2048. TransportName,
  2049. ServiceBitsOfInterest,
  2050. ServiceBits,
  2051. UpdateImmediately);
  2052. NET_REMOTE_RPC_FAILED(
  2053. "I_NetServerSetServiceBitsEx",
  2054. ServerName,
  2055. apiStatus,
  2056. NET_REMOTE_FLAG_NORMAL,
  2057. SERVICE_SERVER)
  2058. //
  2059. // No downlevel call.
  2060. //
  2061. apiStatus = ERROR_NOT_SUPPORTED;
  2062. NET_REMOTE_END
  2063. return(apiStatus);
  2064. } // I_NetServerSetServiceBitsEx
  2065. NET_API_STATUS
  2066. I_NetServerSetServiceBits (
  2067. IN LPTSTR servername,
  2068. IN LPTSTR transportname,
  2069. IN DWORD servicebits,
  2070. IN DWORD updateimmediately
  2071. )
  2072. /*++
  2073. Routine Description:
  2074. This is the DLL entrypoint for I_NetServerSetServiceBits. This
  2075. routine sets the value of the Server Type as sent in server
  2076. announcement messages. It is an internal API used only by the
  2077. service controller.
  2078. Arguments:
  2079. ServerName - Used by RPC to direct the call. This API may only be
  2080. issued locally. This is enforced by the client stub.
  2081. ServiceBits - Bits (preassigned to various components by Microsoft)
  2082. indicating which services are active. This field is not
  2083. interpreted by the server service.
  2084. Return Value:
  2085. NET_API_STATUS - NO_ERROR or ERROR_NOT_SUPPORTED.
  2086. --*/
  2087. {
  2088. NET_API_STATUS apiStatus;
  2089. DWORD localOrRemote;
  2090. //
  2091. // Don't let this API go remote.
  2092. //
  2093. if ((servername != NULL) && (*servername != '\0')) {
  2094. apiStatus = NetpIsRemote(servername, &localOrRemote, NULL, 0);
  2095. if (apiStatus != NERR_Success) {
  2096. return apiStatus;
  2097. }
  2098. if (localOrRemote == ISREMOTE) {
  2099. return ERROR_NOT_SUPPORTED;
  2100. }
  2101. }
  2102. //
  2103. // Do the call.
  2104. //
  2105. NET_REMOTE_TRY_RPC
  2106. apiStatus = I_NetrServerSetServiceBits (
  2107. servername,
  2108. transportname,
  2109. servicebits,
  2110. updateimmediately);
  2111. //
  2112. // This API is called by the Service Controller only. Don't let
  2113. // the failure path call any SCM APIs since that may deadlock
  2114. // services.exe in the loopback.
  2115. //
  2116. NET_REMOTE_RPC_FAILED(
  2117. "I_NetServerSetServiceBits",
  2118. servername,
  2119. apiStatus,
  2120. NET_REMOTE_FLAG_SVC_CTRL,
  2121. SERVICE_SERVER)
  2122. //
  2123. // No downlevel call.
  2124. //
  2125. apiStatus = ERROR_NOT_SUPPORTED;
  2126. NET_REMOTE_END
  2127. return(apiStatus);
  2128. } // I_NetServerSetServiceBits
  2129. //
  2130. // Netps canonicalization functions. These are essentially private functions
  2131. // and are called from the API stubs in canonapi.c. The canonicalization
  2132. // functions have to be usable locally without going via the server service
  2133. // hence they live in NETAPI.DLL, but call local functions in NETLIB if the
  2134. // ServerName parameter is NULL (or designates the local machine). If the
  2135. // ServerName parameter is not NULL and designates a remote computer then the
  2136. // RPC function (here) will be called, hence the remote server must be
  2137. // running in order to make remote canonicalization requests
  2138. //
  2139. NET_API_STATUS
  2140. NET_API_FUNCTION
  2141. NetpsNameCanonicalize(
  2142. IN LPTSTR ServerName,
  2143. IN LPTSTR Name,
  2144. OUT LPTSTR Outbuf,
  2145. IN DWORD OutbufLen,
  2146. IN DWORD NameType,
  2147. IN DWORD Flags
  2148. )
  2149. /*++
  2150. Routine Description:
  2151. Canonicalizes a name
  2152. Arguments:
  2153. ServerName - where to run this API
  2154. Name - name to canonicalize
  2155. Outbuf - where to put canonicalized name
  2156. OutbufLen - length of Outbuf
  2157. NameType - type of name to canonicalize
  2158. Flags - control flags
  2159. Return Value:
  2160. NET_API_STATUS
  2161. --*/
  2162. {
  2163. NET_API_STATUS apiStatus;
  2164. NET_REMOTE_TRY_RPC
  2165. apiStatus = NetprNameCanonicalize(ServerName,
  2166. Name,
  2167. Outbuf,
  2168. OutbufLen,
  2169. NameType,
  2170. Flags
  2171. );
  2172. NET_REMOTE_RPC_FAILED("NetpsNameCanonicalize",
  2173. ServerName,
  2174. apiStatus,
  2175. NET_REMOTE_FLAG_NORMAL,
  2176. SERVICE_SERVER)
  2177. //
  2178. // RPC call didn't work - try down-level routine
  2179. //
  2180. apiStatus = RxNetpNameCanonicalize(ServerName,
  2181. Name,
  2182. Outbuf,
  2183. OutbufLen,
  2184. NameType,
  2185. Flags
  2186. );
  2187. NET_REMOTE_END
  2188. return apiStatus;
  2189. }
  2190. LONG
  2191. NET_API_FUNCTION
  2192. NetpsNameCompare(
  2193. IN LPTSTR ServerName,
  2194. IN LPTSTR Name1,
  2195. IN LPTSTR Name2,
  2196. IN DWORD NameType,
  2197. IN DWORD Flags
  2198. )
  2199. /*++
  2200. Routine Description:
  2201. Compares two names. Must be of same type
  2202. Arguments:
  2203. ServerName - where to run this API
  2204. Name1 - 1st name to compare
  2205. Name2 - 2nd
  2206. NameType - type of names
  2207. Flags - control flags
  2208. Return Value:
  2209. LONG
  2210. --*/
  2211. {
  2212. NET_API_STATUS apiStatus;
  2213. NET_REMOTE_TRY_RPC
  2214. apiStatus = NetprNameCompare(ServerName, Name1, Name2, NameType, Flags);
  2215. NET_REMOTE_RPC_FAILED("NetpsNameCompare",
  2216. ServerName,
  2217. apiStatus,
  2218. NET_REMOTE_FLAG_NORMAL,
  2219. SERVICE_SERVER)
  2220. //
  2221. // RPC call didn't work - try down-level routine
  2222. //
  2223. apiStatus = RxNetpNameCompare(ServerName, Name1, Name2, NameType, Flags);
  2224. NET_REMOTE_END
  2225. return apiStatus;
  2226. }
  2227. NET_API_STATUS
  2228. NET_API_FUNCTION
  2229. NetpsNameValidate(
  2230. IN LPTSTR ServerName,
  2231. IN LPTSTR Name,
  2232. IN DWORD NameType,
  2233. IN DWORD Flags
  2234. )
  2235. /*++
  2236. Routine Description:
  2237. Validates a name - checks whether a name of a certain type conforms to
  2238. canonicalization rules for that name type. Canonicalization rules mean
  2239. character set, name syntax and length
  2240. Arguments:
  2241. ServerName - where to perform this function
  2242. Name - name to validate
  2243. NameType - what type of name it is
  2244. Flags - MBZ
  2245. Return Value:
  2246. NET_API_STATUS
  2247. --*/
  2248. {
  2249. NET_API_STATUS apiStatus;
  2250. NET_REMOTE_TRY_RPC
  2251. apiStatus = NetprNameValidate(ServerName, Name, NameType, Flags);
  2252. NET_REMOTE_RPC_FAILED("NetpsNameValidate",
  2253. ServerName,
  2254. apiStatus,
  2255. NET_REMOTE_FLAG_NORMAL,
  2256. SERVICE_SERVER)
  2257. //
  2258. // RPC call didn't work - try down-level routine
  2259. //
  2260. apiStatus = RxNetpNameValidate(ServerName, Name, NameType, Flags);
  2261. NET_REMOTE_END
  2262. return apiStatus;
  2263. }
  2264. NET_API_STATUS
  2265. NET_API_FUNCTION
  2266. NetpsPathCanonicalize(
  2267. IN LPTSTR ServerName,
  2268. IN LPTSTR PathName,
  2269. OUT LPTSTR Outbuf,
  2270. IN DWORD OutbufLen,
  2271. IN LPTSTR Prefix OPTIONAL,
  2272. IN OUT LPDWORD PathType,
  2273. IN DWORD Flags
  2274. )
  2275. /*++
  2276. Routine Description:
  2277. Canonicalizes a directory path or a device name
  2278. Arguments:
  2279. ServerName - where to run this API
  2280. PathName - path to canonicalize
  2281. Outbuf - where to write the canonicalized version
  2282. OutbufLen - length of Outbuf in bytes
  2283. Prefix - optional prefix which will be prepended to Path
  2284. PathType - the type of path to canonicalize. May be different at output
  2285. Flags - control flags
  2286. Return Value:
  2287. NET_API_STATUS
  2288. --*/
  2289. {
  2290. NET_API_STATUS apiStatus;
  2291. NET_REMOTE_TRY_RPC
  2292. apiStatus = NetprPathCanonicalize(ServerName,
  2293. PathName,
  2294. (LPBYTE)Outbuf,
  2295. OutbufLen,
  2296. Prefix,
  2297. PathType,
  2298. Flags
  2299. );
  2300. NET_REMOTE_RPC_FAILED("NetpsPathCanonicalize",
  2301. ServerName,
  2302. apiStatus,
  2303. NET_REMOTE_FLAG_NORMAL,
  2304. SERVICE_SERVER)
  2305. //
  2306. // RPC call didn't work - try down-level routine
  2307. //
  2308. apiStatus = RxNetpPathCanonicalize(ServerName,
  2309. PathName,
  2310. Outbuf,
  2311. OutbufLen,
  2312. Prefix,
  2313. PathType,
  2314. Flags
  2315. );
  2316. NET_REMOTE_END
  2317. return apiStatus;
  2318. }
  2319. LONG
  2320. NET_API_FUNCTION
  2321. NetpsPathCompare(
  2322. IN LPTSTR ServerName,
  2323. IN LPTSTR PathName1,
  2324. IN LPTSTR PathName2,
  2325. IN DWORD PathType,
  2326. IN DWORD Flags
  2327. )
  2328. /*++
  2329. Routine Description:
  2330. Compares two paths. The paths are assumed to be of the same type
  2331. Arguments:
  2332. ServerName - where to run this API
  2333. PathName1 - 1st path to compare
  2334. PathName2 - 2nd
  2335. PathType - types of paths
  2336. Flags - control flags
  2337. Return Value:
  2338. LONG
  2339. --*/
  2340. {
  2341. NET_API_STATUS apiStatus;
  2342. NET_REMOTE_TRY_RPC
  2343. apiStatus = NetprPathCompare(ServerName,
  2344. PathName1,
  2345. PathName2,
  2346. PathType,
  2347. Flags
  2348. );
  2349. NET_REMOTE_RPC_FAILED("NetpsPathCompare",
  2350. ServerName,
  2351. apiStatus,
  2352. NET_REMOTE_FLAG_NORMAL,
  2353. SERVICE_SERVER)
  2354. //
  2355. // RPC call didn't work - try down-level routine
  2356. //
  2357. apiStatus = RxNetpPathCompare(ServerName,
  2358. PathName1,
  2359. PathName2,
  2360. PathType,
  2361. Flags
  2362. );
  2363. NET_REMOTE_END
  2364. return apiStatus;
  2365. }
  2366. NET_API_STATUS
  2367. NET_API_FUNCTION
  2368. NetpsPathType(
  2369. IN LPTSTR ServerName,
  2370. IN LPTSTR PathName,
  2371. OUT LPDWORD PathType,
  2372. IN DWORD Flags
  2373. )
  2374. /*++
  2375. Routine Description:
  2376. Determines the type of a path
  2377. Arguments:
  2378. ServerName - where to run this API
  2379. PathName - to find type of
  2380. PathType - returned path type
  2381. Flags - control flags
  2382. Return Value:
  2383. NET_API_STATUS
  2384. --*/
  2385. {
  2386. NET_API_STATUS apiStatus;
  2387. NET_REMOTE_TRY_RPC
  2388. apiStatus = NetprPathType(ServerName, PathName, PathType, Flags);
  2389. NET_REMOTE_RPC_FAILED("NetpsPathType",
  2390. ServerName,
  2391. apiStatus,
  2392. NET_REMOTE_FLAG_NORMAL,
  2393. SERVICE_SERVER)
  2394. //
  2395. // RPC call didn't work - try down-level routine
  2396. //
  2397. apiStatus = RxNetpPathType(ServerName, PathName, PathType, Flags);
  2398. NET_REMOTE_END
  2399. return apiStatus;
  2400. }
  2401. NET_API_STATUS NET_API_FUNCTION
  2402. NetServerTransportAddEx (
  2403. IN LPTSTR servername,
  2404. IN DWORD level,
  2405. IN LPBYTE bufptr
  2406. )
  2407. /*++
  2408. Routine Description:
  2409. This is the DLL entrypoint for NetServerTransportAddEx. It functions
  2410. just like NetServerTransportAdd, but it supports level 1 as well as 0
  2411. --*/
  2412. {
  2413. NET_API_STATUS apiStatus;
  2414. NET_REMOTE_TRY_RPC
  2415. apiStatus = NetrServerTransportAddEx (
  2416. servername,
  2417. level,
  2418. (LPTRANSPORT_INFO) bufptr);
  2419. NET_REMOTE_RPC_FAILED(
  2420. "NetServerTransportAddEx",
  2421. servername,
  2422. apiStatus,
  2423. NET_REMOTE_FLAG_NORMAL,
  2424. SERVICE_SERVER)
  2425. //
  2426. // No downlevel call.
  2427. //
  2428. apiStatus = ERROR_NOT_SUPPORTED;
  2429. NET_REMOTE_END
  2430. if( apiStatus == RPC_NT_PROCNUM_OUT_OF_RANGE ) {
  2431. apiStatus = NERR_InvalidAPI;
  2432. }
  2433. return(apiStatus);
  2434. } // NetServerTransportAddEx
  2435. NET_API_STATUS NET_API_FUNCTION
  2436. NetServerComputerNameAdd(
  2437. IN LPWSTR ServerName OPTIONAL,
  2438. IN LPWSTR EmulatedDomainName OPTIONAL,
  2439. IN LPWSTR EmulatedServerName
  2440. )
  2441. /*++
  2442. Routine Description:
  2443. This is the DLL entrypoint for NetServerComputerNameAdd. This api
  2444. causes 'ServerName' to respond to requests for 'EmulatedServerName'.
  2445. Arguments:
  2446. servername --A pointer to an ASCIIZ string containing the name of
  2447. the remote server on which the function is to execute. A NULL
  2448. pointer or string specifies the local machine.
  2449. EmulatedServerName --A pointer to the ASCIIZ string containing the
  2450. name which the server should stop supporting
  2451. EmulatedDomainName --A pointer to the ASCIIZ string containing the
  2452. domain name the server should use when announcing the presence of
  2453. 'EmulatedServerName'
  2454. Return Value:
  2455. NERR_Success, or reason for failure
  2456. --*/
  2457. {
  2458. DWORD resumehandle = 0;
  2459. NET_API_STATUS retval;
  2460. DWORD entriesread, totalentries;
  2461. DWORD i, j;
  2462. BOOLEAN AddedOne = FALSE;
  2463. UCHAR NetBiosName[ MAX_PATH ];
  2464. OEM_STRING NetBiosNameString;
  2465. UNICODE_STRING UniName;
  2466. //
  2467. // Ensure a valid EmulatedServerName was passed in
  2468. //
  2469. if( EmulatedServerName == NULL ) {
  2470. return ERROR_INVALID_PARAMETER;
  2471. }
  2472. //
  2473. // Convert the EmulatedServerName to an OEM string
  2474. //
  2475. RtlInitUnicodeString( &UniName, EmulatedServerName );
  2476. NetBiosNameString.Buffer = (PCHAR)NetBiosName;
  2477. NetBiosNameString.MaximumLength = sizeof( NetBiosName );
  2478. (VOID) RtlUpcaseUnicodeStringToOemString(
  2479. &NetBiosNameString,
  2480. &UniName,
  2481. FALSE
  2482. );
  2483. if( ARGUMENT_PRESENT( EmulatedDomainName ) ) {
  2484. //
  2485. // The caller wants to set a new computer name and domain name to the
  2486. // server. This requires level 1, which is new in 4.0
  2487. //
  2488. PSERVER_TRANSPORT_INFO_1 psti1;
  2489. //
  2490. // Enumerate all the transports so we can add the name and domain
  2491. // to each one.
  2492. //
  2493. retval = NetServerTransportEnum ( ServerName,
  2494. 1,
  2495. (LPBYTE *)&psti1,
  2496. (DWORD)-1,
  2497. &entriesread,
  2498. &totalentries,
  2499. &resumehandle );
  2500. if( retval == NERR_Success ) {
  2501. //
  2502. // Add the new name and domain to all of the transports
  2503. //
  2504. for( i=0; i < entriesread; i++ ) {
  2505. //
  2506. // Make sure we haven't already added to this transport
  2507. //
  2508. for( j = 0; j < i; j++ ) {
  2509. if( wcscmp( psti1[j].svti1_transportname, psti1[i].svti1_transportname ) == 0 )
  2510. break;
  2511. }
  2512. if( i != j )
  2513. continue;
  2514. psti1[i].svti1_transportaddress = NetBiosName;
  2515. psti1[i].svti1_transportaddresslength = strlen( NetBiosName );
  2516. psti1[i].svti1_domain = EmulatedDomainName;
  2517. retval = NetServerTransportAddEx( ServerName, 1, (LPBYTE)&psti1[ i ] );
  2518. if( retval == NERR_Success ) {
  2519. AddedOne = TRUE;
  2520. }
  2521. }
  2522. MIDL_user_free( psti1 );
  2523. }
  2524. } else {
  2525. //
  2526. // The caller just wants to set an alternate server name. Use level 0,
  2527. // since 3.51 servers support level 0
  2528. //
  2529. PSERVER_TRANSPORT_INFO_0 psti0;
  2530. //
  2531. // Enumerate all the transports so we can add the name and domain
  2532. // to each one.
  2533. //
  2534. retval = NetServerTransportEnum ( ServerName,
  2535. 0,
  2536. (LPBYTE *)&psti0,
  2537. (DWORD)-1,
  2538. &entriesread,
  2539. &totalentries,
  2540. &resumehandle );
  2541. if( retval == NERR_Success ) {
  2542. //
  2543. // Add the new name to all of the transports
  2544. //
  2545. for( i=0; i < entriesread; i++ ) {
  2546. //
  2547. // Make sure we haven't already added to this transport
  2548. //
  2549. for( j = 0; j < i; j++ ) {
  2550. if( wcscmp( psti0[j].svti0_transportname, psti0[i].svti0_transportname ) == 0 )
  2551. break;
  2552. }
  2553. if( i != j )
  2554. continue;
  2555. psti0[i].svti0_transportaddress = NetBiosName;
  2556. psti0[i].svti0_transportaddresslength = strlen( NetBiosName );
  2557. retval = NetServerTransportAdd( ServerName, 0, (LPBYTE)&psti0[ i ] );
  2558. if( retval == NERR_Success ) {
  2559. AddedOne = TRUE;
  2560. }
  2561. }
  2562. MIDL_user_free( psti0 );
  2563. }
  2564. }
  2565. return AddedOne ? NERR_Success : retval;
  2566. }
  2567. NET_API_STATUS NET_API_FUNCTION
  2568. NetServerComputerNameDel (
  2569. IN LPWSTR ServerName OPTIONAL,
  2570. IN LPWSTR EmulatedServerName
  2571. )
  2572. /*++
  2573. Routine Description:
  2574. This is the DLL entrypoint for NetServerComputerNameDel. This api
  2575. causes 'ServerName' to cease responding to requests for 'EmulatedServerName'
  2576. Arguments:
  2577. servername --A pointer to an ASCIIZ string containing the name of
  2578. the remote server on which the function is to execute. A NULL
  2579. pointer or string specifies the local machine.
  2580. EmulatedServerName --A pointer to the ASCIIZ string containing the
  2581. name which the server should stop supporting
  2582. Return Value:
  2583. NERR_Success, or reason for failure
  2584. --*/
  2585. {
  2586. DWORD resumehandle = 0;
  2587. NET_API_STATUS retval, tmpretval;
  2588. DWORD entriesread, totalentries;
  2589. DWORD i;
  2590. UCHAR NetBiosName[MAX_PATH];
  2591. OEM_STRING NetBiosNameString;
  2592. UNICODE_STRING UniName;
  2593. PSERVER_TRANSPORT_INFO_0 psti0;
  2594. BOOLEAN nameDeleted = FALSE;
  2595. //
  2596. // Ensure a valid EmulatedServerName was passed in
  2597. //
  2598. if( EmulatedServerName == NULL ) {
  2599. return ERROR_INVALID_PARAMETER;
  2600. }
  2601. //
  2602. // Convert the EmulatedServerName to an OEM string
  2603. //
  2604. RtlInitUnicodeString( &UniName, EmulatedServerName );
  2605. NetBiosNameString.Buffer = (PCHAR)NetBiosName;
  2606. NetBiosNameString.MaximumLength = sizeof( NetBiosName );
  2607. (VOID) RtlUpcaseUnicodeStringToOemString(
  2608. &NetBiosNameString,
  2609. &UniName,
  2610. FALSE
  2611. );
  2612. //
  2613. // Enumerate all the transports so we can delete the name from each one
  2614. //
  2615. retval = NetServerTransportEnum ( ServerName,
  2616. 0,
  2617. (LPBYTE *)&psti0,
  2618. (DWORD)-1,
  2619. &entriesread,
  2620. &totalentries,
  2621. &resumehandle );
  2622. if( retval != NERR_Success ) {
  2623. return retval;
  2624. }
  2625. retval = ERROR_BAD_NET_NAME;
  2626. //
  2627. // Delete the name from all of the transports. If we were successful at least once,
  2628. // then we return success.
  2629. //
  2630. for( i=0; i < entriesread; i++ ) {
  2631. if( psti0[i].svti0_transportaddresslength != NetBiosNameString.Length ) {
  2632. continue;
  2633. }
  2634. if( RtlCompareMemory( psti0[i].svti0_transportaddress,
  2635. NetBiosName,
  2636. NetBiosNameString.Length) != NetBiosNameString.Length ) {
  2637. continue;
  2638. }
  2639. tmpretval = NetServerTransportDel( ServerName, 0, (LPBYTE)&psti0[ i ] );
  2640. if( nameDeleted == FALSE ) {
  2641. retval = tmpretval;
  2642. if( retval == NERR_Success ) {
  2643. nameDeleted = TRUE;
  2644. }
  2645. }
  2646. }
  2647. if( entriesread ) {
  2648. MIDL_user_free( psti0 );
  2649. }
  2650. return retval;
  2651. }