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.

703 lines
16 KiB

  1. /*++
  2. Copyright (c) 1991-1993 Microsoft Corporation
  3. Module Name:
  4. canonapi.c
  5. Abstract:
  6. This file contains the remotable API wrappers for the canonicalization
  7. functions. Now that remotable canonicalization has been moved into the
  8. server service, these canonicalization routines (in NETAPI.DLL) simply
  9. decide whether a function should be remoted or runs the local routine
  10. The canonicalization functions have been split into these wrappers, the
  11. local versions and the remote RPC routines to avoid the cylical dependency
  12. of SRVSVC.DLL/.LIB and NETAPI.DLL/.LIB
  13. Contents:
  14. NetpListCanonicalize
  15. NetpListTraverse
  16. NetpNameCanonicalize
  17. NetpNameCompare
  18. NetpNameValidate
  19. NetpPathCanonicalize
  20. NetpPathCompare
  21. NetpPathType
  22. Author:
  23. Richard L Firth (rfirth) 15-May-1992
  24. Revision History:
  25. --*/
  26. #include <nt.h>
  27. #include <ntrtl.h>
  28. #include <nturtl.h>
  29. #include <windows.h>
  30. #include <lmcons.h>
  31. #include <lmerr.h>
  32. #include <tstring.h>
  33. #include <icanon.h>
  34. #include <netcan.h>
  35. NET_API_STATUS
  36. NET_API_FUNCTION
  37. NetpListCanonicalize(
  38. IN LPTSTR ServerName OPTIONAL,
  39. IN LPTSTR List,
  40. IN LPTSTR Delimiters OPTIONAL,
  41. OUT LPTSTR Outbuf,
  42. IN DWORD OutbufLen,
  43. OUT LPDWORD OutCount,
  44. OUT LPDWORD PathTypes,
  45. IN DWORD PathTypesLen,
  46. IN DWORD Flags
  47. )
  48. /*++
  49. Routine Description:
  50. Converts a list to its canonical form. If ServerName is non-NULL then the
  51. RPC function is called (in SRVSVC.DLL) else the local worker function (in
  52. NETLIB.LIB)
  53. Arguments:
  54. ServerName - where to remote this function. May be NULL
  55. List - input list to canonicalize
  56. Delimiters - optional list of delimiter characters. May be NULL
  57. Outbuf - place to write output
  58. OutbufLen - length of Outbuf
  59. OutCount - returned number of items in Outbuf
  60. PathTypes - returned list of types of entries in Outbuf
  61. PathTypesLen - size of PathTypes array
  62. Flags - control flags
  63. Return Value:
  64. NET_API_STATUS
  65. --*/
  66. {
  67. NET_API_STATUS status = 0;
  68. DWORD location;
  69. TCHAR serverName[MAX_PATH];
  70. DWORD val;
  71. BOOL nullDelimiter = FALSE;
  72. TCHAR ch;
  73. //
  74. // validate parameters
  75. //
  76. try {
  77. if (ARGUMENT_PRESENT(ServerName)) {
  78. val = STRLEN(ServerName);
  79. }
  80. if (ARGUMENT_PRESENT(Delimiters)) {
  81. val = STRLEN(Delimiters);
  82. nullDelimiter = (val == 0);
  83. } else {
  84. nullDelimiter = TRUE;
  85. }
  86. val = STRLEN(List);
  87. //
  88. // if Delimiters is a NULL pointer or NUL string, then List is a
  89. // NULL-NULL input list
  90. //
  91. if (nullDelimiter) {
  92. LPTSTR str = List + val + 1;
  93. do {
  94. val = STRLEN(str);
  95. str += val + 1;
  96. } while ( val );
  97. }
  98. ch = *((TCHAR volatile *)Outbuf);
  99. *Outbuf = ch;
  100. ch = *((TCHAR volatile *)(Outbuf + OutbufLen/sizeof(*Outbuf) - sizeof(*Outbuf)));
  101. *(Outbuf + OutbufLen/sizeof(*Outbuf) - sizeof(*Outbuf)) = ch;
  102. *OutCount = 0;
  103. if (ARGUMENT_PRESENT(PathTypes)) {
  104. PathTypes[0] = 0;
  105. PathTypes[PathTypesLen - 1] = 0;
  106. } else if ((Flags & INLC_FLAGS_MASK_NAMETYPE) == NAMETYPE_PATH) {
  107. //
  108. // NAMETYPE_PATH and NULL PathTypes is illegal
  109. //
  110. status = ERROR_INVALID_PARAMETER;
  111. }
  112. } except(EXCEPTION_EXECUTE_HANDLER) {
  113. status = ERROR_INVALID_PARAMETER;
  114. }
  115. if (status) {
  116. return status;
  117. }
  118. if (Flags & INLC_FLAGS_MASK_RESERVED) {
  119. return ERROR_INVALID_PARAMETER;
  120. }
  121. //
  122. // call client-side RPC routine or local canonicalization routine
  123. //
  124. status = NetpIsRemote(ServerName, &location, serverName, 0);
  125. if (status != NERR_Success) {
  126. return status;
  127. }
  128. //
  129. // due to historic precedent, we don't remote this function
  130. //
  131. if (location == ISREMOTE) {
  132. return ERROR_NOT_SUPPORTED;
  133. } else {
  134. return NetpwListCanonicalize(List,
  135. Delimiters,
  136. Outbuf,
  137. OutbufLen,
  138. OutCount,
  139. PathTypes,
  140. PathTypesLen,
  141. Flags
  142. );
  143. }
  144. }
  145. LPTSTR
  146. NET_API_FUNCTION
  147. NetpListTraverse(
  148. IN LPTSTR Reserved OPTIONAL,
  149. IN LPTSTR* pList,
  150. IN DWORD Flags
  151. )
  152. /*++
  153. Routine Description:
  154. This just calls the local traverse function
  155. Arguments:
  156. Reserved - MBZ
  157. pList - pointer to list to traverse
  158. Flags - MBZ
  159. Return Value:
  160. LPTSTR
  161. --*/
  162. {
  163. return NetpwListTraverse(Reserved, pList, Flags);
  164. }
  165. NET_API_STATUS
  166. NET_API_FUNCTION
  167. NetpNameCanonicalize(
  168. IN LPTSTR ServerName OPTIONAL,
  169. IN LPTSTR Name,
  170. OUT LPTSTR Outbuf,
  171. IN DWORD OutbufLen,
  172. IN DWORD NameType,
  173. IN DWORD Flags
  174. )
  175. /*++
  176. Routine Description:
  177. Canonicalizes a name
  178. Arguments:
  179. ServerName - where to run this API
  180. Name - name to canonicalize
  181. Outbuf - where to put canonicalized name
  182. OutbufLen - length of Outbuf
  183. NameType - type of name to canonicalize
  184. Flags - control flags
  185. Return Value:
  186. NET_API_STATUS
  187. --*/
  188. {
  189. NET_API_STATUS status = 0;
  190. DWORD location;
  191. TCHAR serverName[MAX_PATH];
  192. DWORD val;
  193. TCHAR ch;
  194. //
  195. // validate parameters
  196. //
  197. try {
  198. if (ARGUMENT_PRESENT(ServerName)) {
  199. val = STRLEN(ServerName);
  200. }
  201. if (ARGUMENT_PRESENT(Name)) {
  202. val = STRLEN(Name);
  203. }
  204. if (ARGUMENT_PRESENT(Outbuf)) {
  205. ch = *((TCHAR volatile *)Outbuf);
  206. *Outbuf = ch;
  207. ch = *((TCHAR volatile *)(Outbuf + OutbufLen/sizeof(*Outbuf) - sizeof(*Outbuf)));
  208. *(Outbuf + OutbufLen/sizeof(*Outbuf) - sizeof(*Outbuf)) = ch;
  209. } else {
  210. status = ERROR_INVALID_PARAMETER;
  211. }
  212. } except(EXCEPTION_EXECUTE_HANDLER) {
  213. status = ERROR_INVALID_PARAMETER;
  214. }
  215. if (status) {
  216. return status;
  217. }
  218. if (Flags & INNCA_FLAGS_RESERVED) {
  219. return ERROR_INVALID_PARAMETER;
  220. }
  221. //
  222. // call client-side RPC routine or local canonicalization routine
  223. //
  224. status = NetpIsRemote(ServerName, &location, serverName, 0);
  225. if (status != NERR_Success) {
  226. return status;
  227. }
  228. if (location == ISREMOTE) {
  229. return NetpsNameCanonicalize(serverName,
  230. Name,
  231. Outbuf,
  232. OutbufLen,
  233. NameType,
  234. Flags
  235. );
  236. } else {
  237. return NetpwNameCanonicalize(Name, Outbuf, OutbufLen, NameType, Flags);
  238. }
  239. }
  240. LONG
  241. NET_API_FUNCTION
  242. NetpNameCompare(
  243. IN LPTSTR ServerName OPTIONAL,
  244. IN LPTSTR Name1,
  245. IN LPTSTR Name2,
  246. IN DWORD NameType,
  247. IN DWORD Flags
  248. )
  249. /*++
  250. Routine Description:
  251. Compares two names. Must be of same type
  252. Arguments:
  253. ServerName - where to run this API
  254. Name1 - 1st name to compare
  255. Name2 - 2nd
  256. NameType - type of names
  257. Flags - control flags
  258. Return Value:
  259. LONG
  260. --*/
  261. {
  262. NET_API_STATUS status = 0;
  263. DWORD location;
  264. TCHAR serverName[MAX_PATH];
  265. DWORD val;
  266. //
  267. // validate parameters
  268. //
  269. try {
  270. if (ARGUMENT_PRESENT(ServerName)) {
  271. val = STRLEN(ServerName);
  272. }
  273. val = STRLEN(Name1);
  274. val = STRLEN(Name2);
  275. } except(EXCEPTION_EXECUTE_HANDLER) {
  276. status = ERROR_INVALID_PARAMETER;
  277. }
  278. if (status) {
  279. return ERROR_INVALID_PARAMETER;
  280. }
  281. if (Flags & INNC_FLAGS_RESERVED) {
  282. return ERROR_INVALID_PARAMETER;
  283. }
  284. //
  285. // call client-side RPC routine or local canonicalization routine
  286. //
  287. status = NetpIsRemote(ServerName, &location, serverName, 0);
  288. if (status != NERR_Success) {
  289. return status;
  290. }
  291. if (location == ISREMOTE) {
  292. return NetpsNameCompare(serverName, Name1, Name2, NameType, Flags);
  293. } else {
  294. return NetpwNameCompare(Name1, Name2, NameType, Flags);
  295. }
  296. }
  297. NET_API_STATUS
  298. NET_API_FUNCTION
  299. NetpNameValidate(
  300. IN LPTSTR ServerName OPTIONAL,
  301. IN LPTSTR Name,
  302. IN DWORD NameType,
  303. IN DWORD Flags
  304. )
  305. /*++
  306. Routine Description:
  307. Validates a name - checks whether a name of a certain type conforms to
  308. canonicalization rules for that name type. Canonicalization rules mean
  309. character set, name syntax and length
  310. Arguments:
  311. ServerName - where to perform this function
  312. Name - name to validate
  313. NameType - what type of name it is
  314. Flags - MBZ
  315. Return Value:
  316. NET_API_STATUS
  317. --*/
  318. {
  319. NET_API_STATUS status = 0;
  320. DWORD location;
  321. TCHAR serverName[MAX_PATH];
  322. DWORD val;
  323. //
  324. // validate parameters
  325. //
  326. try {
  327. if (ARGUMENT_PRESENT(ServerName)) {
  328. val = STRLEN(ServerName);
  329. }
  330. if (ARGUMENT_PRESENT(Name)) {
  331. val = STRLEN(Name);
  332. } else {
  333. status = ERROR_INVALID_PARAMETER;
  334. }
  335. } except(EXCEPTION_EXECUTE_HANDLER) {
  336. status = ERROR_INVALID_PARAMETER;
  337. }
  338. if (status) {
  339. return status;
  340. }
  341. if (Flags & INNV_FLAGS_RESERVED) {
  342. return ERROR_INVALID_PARAMETER;
  343. }
  344. //
  345. // call client-side RPC routine or local canonicalization routine
  346. //
  347. status = NetpIsRemote(ServerName, &location, serverName, 0);
  348. if (status != NERR_Success) {
  349. return status;
  350. }
  351. if (location == ISREMOTE) {
  352. return NetpsNameValidate(serverName, Name, NameType, Flags);
  353. } else {
  354. return NetpwNameValidate(Name, NameType, Flags);
  355. }
  356. }
  357. NET_API_STATUS
  358. NET_API_FUNCTION
  359. NetpPathCanonicalize(
  360. IN LPTSTR ServerName OPTIONAL,
  361. IN LPTSTR PathName,
  362. OUT LPTSTR Outbuf,
  363. IN DWORD OutbufLen,
  364. IN LPTSTR Prefix OPTIONAL,
  365. IN OUT LPDWORD PathType,
  366. IN DWORD Flags
  367. )
  368. /*++
  369. Routine Description:
  370. Canonicalizes a directory path or a device name
  371. Arguments:
  372. ServerName - where to run this API
  373. PathName - path to canonicalize
  374. Outbuf - where to write the canonicalized version
  375. OutbufLen - length of Outbuf in bytes
  376. Prefix - optional prefix which will be prepended to Path
  377. PathType - the type of path to canonicalize. May be different at output
  378. Flags - control flags
  379. Return Value:
  380. NET_API_STATUS
  381. --*/
  382. {
  383. NET_API_STATUS status = 0;
  384. DWORD location;
  385. TCHAR serverName[MAX_PATH];
  386. DWORD val;
  387. TCHAR ch;
  388. //
  389. // validate parameters
  390. //
  391. try {
  392. if (ARGUMENT_PRESENT(ServerName)) {
  393. val = STRLEN(ServerName);
  394. }
  395. if (ARGUMENT_PRESENT(PathName)) {
  396. val = STRLEN(PathName);
  397. }
  398. if (ARGUMENT_PRESENT(Prefix)) {
  399. val = STRLEN(Prefix);
  400. }
  401. if (ARGUMENT_PRESENT(Outbuf)) {
  402. ch = *((TCHAR volatile *)Outbuf);
  403. *Outbuf = ch;
  404. ch = *((TCHAR volatile *)(Outbuf+OutbufLen/sizeof(*Outbuf) - sizeof(*Outbuf)));
  405. *(Outbuf+OutbufLen/sizeof(*Outbuf) - sizeof(*Outbuf)) = ch;
  406. } else {
  407. status = ERROR_INVALID_PARAMETER;
  408. }
  409. val = *PathType ^ 0xf0f0f0f0;
  410. *PathType = val ^ 0xf0f0f0f0;
  411. } except(EXCEPTION_EXECUTE_HANDLER) {
  412. status = ERROR_INVALID_PARAMETER;
  413. }
  414. if (status) {
  415. return status;
  416. }
  417. if (Flags & INPCA_FLAGS_RESERVED) {
  418. return ERROR_INVALID_PARAMETER;
  419. }
  420. //
  421. // call client-side RPC routine or local canonicalization routine
  422. //
  423. status = NetpIsRemote(ServerName, &location, serverName, 0);
  424. if (status != NERR_Success) {
  425. return status;
  426. }
  427. if (location == ISREMOTE) {
  428. return NetpsPathCanonicalize(serverName,
  429. PathName,
  430. Outbuf,
  431. OutbufLen,
  432. Prefix,
  433. PathType,
  434. Flags
  435. );
  436. } else {
  437. return NetpwPathCanonicalize(PathName,
  438. Outbuf,
  439. OutbufLen,
  440. Prefix,
  441. PathType,
  442. Flags
  443. );
  444. }
  445. }
  446. LONG
  447. NET_API_FUNCTION
  448. NetpPathCompare(
  449. IN LPTSTR ServerName OPTIONAL,
  450. IN LPTSTR PathName1,
  451. IN LPTSTR PathName2,
  452. IN DWORD PathType,
  453. IN DWORD Flags
  454. )
  455. /*++
  456. Routine Description:
  457. Compares two paths. The paths are assumed to be of the same type
  458. Arguments:
  459. ServerName - where to run this API
  460. PathName1 - 1st path to compare
  461. PathName2 - 2nd
  462. PathType - types of paths
  463. Flags - control flags
  464. Return Value:
  465. LONG
  466. --*/
  467. {
  468. NET_API_STATUS status = 0;
  469. DWORD location;
  470. TCHAR serverName[MAX_PATH];
  471. DWORD val;
  472. //
  473. // validate parameters
  474. //
  475. try {
  476. if (ARGUMENT_PRESENT(ServerName)) {
  477. val = STRLEN(ServerName);
  478. }
  479. if (ARGUMENT_PRESENT(PathName1)) {
  480. val = STRLEN(PathName1);
  481. }
  482. if (ARGUMENT_PRESENT(PathName2)) {
  483. val = STRLEN(PathName2);
  484. }
  485. } except(EXCEPTION_EXECUTE_HANDLER) {
  486. status = ERROR_INVALID_PARAMETER;
  487. }
  488. if (status) {
  489. return status;
  490. }
  491. if (Flags & INPC_FLAGS_RESERVED) {
  492. return ERROR_INVALID_PARAMETER;
  493. }
  494. //
  495. // call client-side RPC routine or local canonicalization routine
  496. //
  497. status = NetpIsRemote(ServerName, &location, serverName, 0);
  498. if (status != NERR_Success) {
  499. return status;
  500. }
  501. if (location == ISREMOTE) {
  502. return NetpsPathCompare(serverName, PathName1, PathName2, PathType, Flags);
  503. } else {
  504. return NetpwPathCompare(PathName1, PathName2, PathType, Flags);
  505. }
  506. }
  507. NET_API_STATUS
  508. NET_API_FUNCTION
  509. NetpPathType(
  510. IN LPTSTR ServerName OPTIONAL,
  511. IN LPTSTR PathName,
  512. OUT LPDWORD PathType,
  513. IN DWORD Flags
  514. )
  515. /*++
  516. Routine Description:
  517. Determines the type of a path
  518. Arguments:
  519. ServerName - where to run this API
  520. PathName - to find type of
  521. PathType - returned path type
  522. Flags - control flags
  523. Return Value:
  524. NET_API_STATUS
  525. --*/
  526. {
  527. NET_API_STATUS status = 0;
  528. DWORD location;
  529. TCHAR serverName[MAX_PATH];
  530. DWORD val;
  531. //
  532. // validate parameters
  533. //
  534. try {
  535. if (ARGUMENT_PRESENT(ServerName)) {
  536. val = STRLEN(ServerName);
  537. }
  538. if (ARGUMENT_PRESENT(PathName)) {
  539. val = STRLEN(PathName);
  540. } else {
  541. val = 0;
  542. }
  543. if (!val || (val > MAX_PATH - 1)) {
  544. status = ERROR_INVALID_NAME;
  545. }
  546. *PathType = 0;
  547. } except(EXCEPTION_EXECUTE_HANDLER) {
  548. status = ERROR_INVALID_PARAMETER;
  549. }
  550. if (status) {
  551. return status;
  552. }
  553. if (Flags & INPT_FLAGS_RESERVED) {
  554. return ERROR_INVALID_PARAMETER;
  555. }
  556. //
  557. // call client-side RPC routine or local canonicalization routine
  558. //
  559. status = NetpIsRemote(ServerName, &location, serverName, 0);
  560. if (status != NERR_Success) {
  561. return status;
  562. }
  563. if (location == ISREMOTE) {
  564. return NetpsPathType(serverName, PathName, PathType, Flags);
  565. } else {
  566. return NetpwPathType(PathName, PathType, Flags);
  567. }
  568. }