Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

581 lines
24 KiB

  1. /*++
  2. Copyright (c) 1991-1993 Microsoft Corporation
  3. Module Name:
  4. ConvSrv.c
  5. Abstract:
  6. This file contains routines to convert between old and new server
  7. info levels.
  8. Author:
  9. John Rogers (JohnRo) 02-May-1991
  10. Environment:
  11. Portable to any flat, 32-bit environment. (Uses Win32 typedefs.)
  12. Requires ANSI C extensions: slash-slash comments, long external names.
  13. Revision History:
  14. 02-May-1991 JohnRo
  15. Created.
  16. 11-May-1991 JohnRo
  17. Added level 402,403 support. Use PLATFORM_ID equates from lncons.h.
  18. 19-May-1991 JohnRo
  19. Clean up LPBYTE vs. LPTSTR handling, as suggested by PC-LINT.
  20. 05-Jun-1991 JohnRo
  21. Added level 101 to 1 conversion. Also 100 to 0 and 102 to 2.
  22. Added support for sv403_autopath.
  23. Added more debug output when we fail.
  24. 07-Jun-1991 JohnRo
  25. Really added 102 to 2 conversion.
  26. 14-Jun-1991 JohnRo
  27. For debug, display the entire incoming structure.
  28. 18-Jun-1991 JohnRo
  29. Added svX_licenses support.
  30. 08-Aug-1991 JohnRo
  31. Implement downlevel NetWksta APIs. (Moved DanHi's NetCmd/Map32/MServer
  32. stuff here.)
  33. 21-Nov-1991 JohnRo
  34. Removed NT dependencies to reduce recompiles.
  35. 05-May-1993 JohnRo
  36. RAID 8720: bad data from WFW can cause RxNetServerEnum GP fault.
  37. Avoid compiler warnings.
  38. Minor debug output changes.
  39. Use PREFIX_ equates.
  40. Made changes suggested by PC-LINT 5.0
  41. --*/
  42. // These must be included first:
  43. #include <windef.h> // IN, LPVOID, etc.
  44. #include <lmcons.h> // NET_API_STATUS, CNLEN, etc.
  45. // These may be included in any order:
  46. #include <debuglib.h> // IF_DEBUG(CONVSRV).
  47. #include <dlserver.h> // Old info levels, MAX_ equates, my prototype.
  48. #include <lmapibuf.h> // NetapipBufferAllocate().
  49. #include <lmerr.h> // NERR_ and ERROR_ equates.
  50. #include <lmserver.h> // New info level structures & conv routines.
  51. #include <mapsupp.h> // NetpMoveStrings().
  52. #include <netdebug.h> // NetpKdPrint(()), FORMAT_ equates, etc.
  53. #include <netlib.h> // NetpPointerPlusSomeBytes().
  54. #include <prefix.h> // PREFIX_ equates.
  55. #include <tstr.h> // STRLEN().
  56. #include <xsdef16.h> // xactsrv defaults for values not supported on NT
  57. NET_API_STATUS
  58. NetpConvertServerInfo (
  59. IN DWORD FromLevel,
  60. IN LPVOID FromInfo,
  61. IN BOOL FromNative,
  62. IN DWORD ToLevel,
  63. OUT LPVOID ToInfo,
  64. IN DWORD ToFixedSize,
  65. IN DWORD ToStringSize,
  66. IN BOOL ToNative,
  67. IN OUT LPTSTR * ToStringTopPtr OPTIONAL
  68. )
  69. /*++
  70. Routine Description:
  71. NetpConvertServerInfo handles "old" (LanMan 2.x) and "new" (portable
  72. LanMan, including NT/LAN) server info levels. Only certain pairs of
  73. conversions are allowed:
  74. 0 to 100
  75. 1 to 101
  76. 2 to 102
  77. 2 to 402
  78. 3 to 403
  79. 100 to 0
  80. 101 to 1
  81. 102 to 2
  82. Arguments:
  83. FromLevel - a DWORD which gives the info level being converted from.
  84. FromInfo - the actual data being converted.
  85. FromNative - a BOOLEAN indicating whether or not FromInfo is in native
  86. (local machine) format, as opposed to "RAP" format.
  87. ToLevel - a DWORD which gives the info level being converted to.
  88. ToInfo - Points to an area which will contain the converted
  89. info structure.
  90. ToFixedSize - Size of the ToInfo fixed area, in bytes.
  91. ToStringSize - Size of the ToStringTopPtr string area, in bytes.
  92. ToNative - a BOOLEAN indicating whether or not the "to" info is to be
  93. in native (local machine) format, as opposed to "RAP" format.
  94. ToStringTopPtr - optionally points a pointer to the top of the area to be
  95. used for variable-length items. If ToStringTopPtr is NULL, then
  96. NetpConvertServerInfo will use ToInfo+ToFixedSize as this area.
  97. Otherwise, this routine will update *ToStringTopPtr. This allows
  98. this routine to be used to convert arrays of entries.
  99. Return Value:
  100. NET_API_STATUS - NERR_Success, ERROR_INVALID_LEVEL, etc.
  101. --*/
  102. {
  103. BOOL CopyOK;
  104. LPBYTE ToFixedEnd;
  105. DWORD ToInfoSize;
  106. LPTSTR ToStringTop;
  107. //
  108. // These parameters are not used in non-debug code for the moment.
  109. // ToLevel might be used in the future, if we allow more combinations of
  110. // level conversions. FromNative and ToNative will eventually be used
  111. // by RapConvertSingleEntry.
  112. //
  113. DBG_UNREFERENCED_PARAMETER(CopyOK); // debug only
  114. NetpAssert(FromNative == TRUE);
  115. DBG_UNREFERENCED_PARAMETER(FromNative);
  116. DBG_UNREFERENCED_PARAMETER(ToLevel);
  117. NetpAssert(ToNative == TRUE);
  118. DBG_UNREFERENCED_PARAMETER(ToNative);
  119. // Check caller's parameters for null pointers.
  120. if (FromInfo==NULL) {
  121. NetpKdPrint(( PREFIX_NETLIB
  122. "NetpConvertServerInfo: invalid FromInfo pointer.\n" ));
  123. return (ERROR_INVALID_PARAMETER);
  124. } else if (ToInfo==NULL) {
  125. NetpKdPrint(( PREFIX_NETLIB
  126. "NetpConvertServerInfo: invalid ToInfo pointer.\n" ));
  127. return (ERROR_INVALID_PARAMETER);
  128. }
  129. // Set up pointers for use by NetpCopyStringsToBuffer.
  130. if (ToStringTopPtr != NULL) {
  131. ToStringTop = *ToStringTopPtr;
  132. } else {
  133. ToStringTop = (LPTSTR)
  134. NetpPointerPlusSomeBytes(ToInfo, ToFixedSize+ToStringSize);
  135. }
  136. ToInfoSize = ToFixedSize + ToStringSize;
  137. ToFixedEnd = NetpPointerPlusSomeBytes(ToInfo, ToFixedSize);
  138. // Make sure info levels are OK and caller didn't mess up otherwise.
  139. NetpAssert(ToInfoSize > 0);
  140. switch (FromLevel) {
  141. case 0 :
  142. NetpAssert(ToLevel == 100);
  143. break;
  144. case 1 :
  145. NetpAssert(ToLevel == 101);
  146. break;
  147. case 2 :
  148. NetpAssert( (ToLevel == 102) || (ToLevel == 402) );
  149. break;
  150. case 3 :
  151. NetpAssert(ToLevel == 403);
  152. break;
  153. case 100 :
  154. NetpAssert(ToLevel == 0);
  155. break;
  156. case 101 :
  157. NetpAssert(ToLevel == 1);
  158. break;
  159. case 102 :
  160. NetpAssert(ToLevel == 2);
  161. break;
  162. default :
  163. NetpKdPrint(( PREFIX_NETLIB
  164. "NetpConvertServerInfo: invalid FromLevel ("
  165. FORMAT_DWORD ").\n", FromLevel ));
  166. return (ERROR_INVALID_LEVEL);
  167. }
  168. // Convert fields. This is done with a "switch" that takes advantage
  169. // of the fact that certain info levels are subsets of other ones.
  170. switch (FromLevel) {
  171. case 102 :
  172. {
  173. LPSERVER_INFO_2 psv2 = ToInfo;
  174. LPSERVER_INFO_102 psv102 = FromInfo;
  175. // Do unique fields for level 1.
  176. psv2->sv2_users = psv102->sv102_users;
  177. psv2->sv2_disc = psv102->sv102_disc;
  178. if (psv102->sv102_hidden) {
  179. psv2->sv2_hidden = SV_HIDDEN;
  180. } else {
  181. psv2->sv2_hidden = SV_VISIBLE;
  182. }
  183. psv2->sv2_announce = psv102->sv102_announce;
  184. psv2->sv2_anndelta = psv102->sv102_anndelta;
  185. psv2->sv2_licenses = psv102->sv102_licenses;
  186. NetpAssert(psv102->sv102_userpath != NULL); // Avoid STRLEN err.
  187. CopyOK = NetpCopyStringToBuffer (
  188. psv102->sv102_userpath, // in string
  189. STRLEN(psv102->sv102_userpath), // input string length
  190. ToFixedEnd, // fixed data end
  191. & ToStringTop, // var area end (ptr updated)
  192. & psv2->sv2_userpath); // output string pointer
  193. NetpAssert(CopyOK);
  194. // Make sure it's OK to use level 101 => level 1 code.
  195. CHECK_SERVER_OFFSETS( 1, 2, version_major);
  196. CHECK_SERVER_OFFSETS(101, 102, version_major);
  197. CHECK_SERVER_OFFSETS( 1, 2, version_minor);
  198. CHECK_SERVER_OFFSETS(101, 102, version_minor);
  199. CHECK_SERVER_OFFSETS( 1, 2, type);
  200. CHECK_SERVER_OFFSETS(101, 102, type);
  201. CHECK_SERVER_OFFSETS( 1, 2, comment);
  202. CHECK_SERVER_OFFSETS(101, 102, comment);
  203. }
  204. /* FALLTHROUGH */
  205. case 101 :
  206. {
  207. LPSERVER_INFO_1 psv1 = ToInfo;
  208. LPSERVER_INFO_101 psv101 = FromInfo;
  209. // Do unique fields for level 1.
  210. psv1->sv1_version_major = psv101->sv101_version_major;
  211. psv1->sv1_version_minor = psv101->sv101_version_minor;
  212. psv1->sv1_type = psv101->sv101_type;
  213. NetpAssert(psv101->sv101_comment != NULL); // Avoid STRLEN err.
  214. CopyOK = NetpCopyStringToBuffer (
  215. psv101->sv101_comment, // in string
  216. STRLEN(psv101->sv101_comment), // input string length
  217. ToFixedEnd, // fixed data end
  218. & ToStringTop, // var area end (ptr updated)
  219. & psv1->sv1_comment); // output string pointer
  220. NetpAssert(CopyOK);
  221. // Make sure it's OK to use level 100 => level 0 code.
  222. CHECK_SERVER_OFFSETS( 0, 1, name);
  223. CHECK_SERVER_OFFSETS(100, 101, name);
  224. }
  225. /* FALLTHROUGH */
  226. case 100 :
  227. {
  228. LPSERVER_INFO_0 psv0 = ToInfo;
  229. LPSERVER_INFO_100 psv100 = FromInfo;
  230. // All fields are unique for level 0.
  231. NetpAssert(psv100->sv100_name != NULL); // Avoid STRLEN err.
  232. CopyOK = NetpCopyStringToBuffer (
  233. psv100->sv100_name, // in string
  234. STRLEN(psv100->sv100_name), // input string length
  235. ToFixedEnd, // fixed data end
  236. & ToStringTop, // var area end (ptr updated)
  237. & psv0->sv0_name); // output string pointer
  238. NetpAssert(CopyOK);
  239. }
  240. break;
  241. case 3 :
  242. {
  243. LPSERVER_INFO_3 psv3 = FromInfo;
  244. LPSERVER_INFO_403 psv403 = ToInfo;
  245. // Do unique fields for level 403.
  246. psv403->sv403_auditedevents = psv3->sv3_auditedevents;
  247. psv403->sv403_autoprofile = psv3->sv3_autoprofile;
  248. NetpAssert(psv3->sv3_autopath != NULL); // avoid STRLEN err.
  249. CopyOK = NetpCopyStringToBuffer (
  250. psv3->sv3_autopath, // in string
  251. STRLEN(psv3->sv3_autopath), // input string length
  252. ToFixedEnd, // fixed data end
  253. & ToStringTop, // var area end (ptr updated)
  254. & psv403->sv403_autopath); // output string pointer
  255. NetpAssert(CopyOK);
  256. // Make sure it's OK to fall through to next level conv.
  257. CHECK_SERVER_OFFSETS( 2, 3, ulist_mtime);
  258. CHECK_SERVER_OFFSETS( 2, 3, glist_mtime);
  259. CHECK_SERVER_OFFSETS( 2, 3, alist_mtime);
  260. CHECK_SERVER_OFFSETS( 2, 3, alerts);
  261. CHECK_SERVER_OFFSETS( 2, 3, security);
  262. CHECK_SERVER_OFFSETS( 2, 3, numadmin);
  263. CHECK_SERVER_OFFSETS( 2, 3, lanmask);
  264. CHECK_SERVER_OFFSETS( 2, 3, guestacct);
  265. CHECK_SERVER_OFFSETS( 2, 3, chdevs);
  266. CHECK_SERVER_OFFSETS( 2, 3, chdevq);
  267. CHECK_SERVER_OFFSETS( 2, 3, chdevjobs);
  268. CHECK_SERVER_OFFSETS( 2, 3, connections);
  269. CHECK_SERVER_OFFSETS( 2, 3, shares);
  270. CHECK_SERVER_OFFSETS( 2, 3, openfiles);
  271. CHECK_SERVER_OFFSETS( 2, 3, sessopens);
  272. CHECK_SERVER_OFFSETS( 2, 3, sessvcs);
  273. CHECK_SERVER_OFFSETS( 2, 3, sessreqs);
  274. CHECK_SERVER_OFFSETS( 2, 3, opensearch);
  275. CHECK_SERVER_OFFSETS( 2, 3, activelocks);
  276. CHECK_SERVER_OFFSETS( 2, 3, numreqbuf);
  277. CHECK_SERVER_OFFSETS( 2, 3, sizreqbuf);
  278. CHECK_SERVER_OFFSETS( 2, 3, numbigbuf);
  279. CHECK_SERVER_OFFSETS( 2, 3, numfiletasks);
  280. CHECK_SERVER_OFFSETS( 2, 3, alertsched);
  281. CHECK_SERVER_OFFSETS( 2, 3, erroralert);
  282. CHECK_SERVER_OFFSETS( 2, 3, logonalert);
  283. CHECK_SERVER_OFFSETS( 2, 3, accessalert);
  284. CHECK_SERVER_OFFSETS( 2, 3, diskalert);
  285. CHECK_SERVER_OFFSETS( 2, 3, netioalert);
  286. CHECK_SERVER_OFFSETS( 2, 3, maxauditsz);
  287. CHECK_SERVER_OFFSETS( 2, 3, srvheuristics);
  288. CHECK_SERVER_OFFSETS(402, 403, ulist_mtime);
  289. CHECK_SERVER_OFFSETS(402, 403, glist_mtime);
  290. CHECK_SERVER_OFFSETS(402, 403, alist_mtime);
  291. CHECK_SERVER_OFFSETS(402, 403, alerts);
  292. CHECK_SERVER_OFFSETS(402, 403, security);
  293. CHECK_SERVER_OFFSETS(402, 403, numadmin);
  294. CHECK_SERVER_OFFSETS(402, 403, lanmask);
  295. CHECK_SERVER_OFFSETS(402, 403, guestacct);
  296. CHECK_SERVER_OFFSETS(402, 403, chdevs);
  297. CHECK_SERVER_OFFSETS(402, 403, chdevq);
  298. CHECK_SERVER_OFFSETS(402, 403, chdevjobs);
  299. CHECK_SERVER_OFFSETS(402, 403, connections);
  300. CHECK_SERVER_OFFSETS(402, 403, shares);
  301. CHECK_SERVER_OFFSETS(402, 403, openfiles);
  302. CHECK_SERVER_OFFSETS(402, 403, sessopens);
  303. CHECK_SERVER_OFFSETS(402, 403, sessvcs);
  304. CHECK_SERVER_OFFSETS(402, 403, sessreqs);
  305. CHECK_SERVER_OFFSETS(402, 403, opensearch);
  306. CHECK_SERVER_OFFSETS(402, 403, activelocks);
  307. CHECK_SERVER_OFFSETS(402, 403, numreqbuf);
  308. CHECK_SERVER_OFFSETS(402, 403, sizreqbuf);
  309. CHECK_SERVER_OFFSETS(402, 403, numbigbuf);
  310. CHECK_SERVER_OFFSETS(402, 403, numfiletasks);
  311. CHECK_SERVER_OFFSETS(402, 403, alertsched);
  312. CHECK_SERVER_OFFSETS(402, 403, erroralert);
  313. CHECK_SERVER_OFFSETS(402, 403, logonalert);
  314. CHECK_SERVER_OFFSETS(402, 403, accessalert);
  315. CHECK_SERVER_OFFSETS(402, 403, diskalert);
  316. CHECK_SERVER_OFFSETS(402, 403, netioalert);
  317. CHECK_SERVER_OFFSETS(402, 403, maxauditsz);
  318. CHECK_SERVER_OFFSETS(402, 403, srvheuristics);
  319. }
  320. /* FALLTHROUGH */
  321. case 2 :
  322. {
  323. LPSERVER_INFO_2 psv2 = FromInfo;
  324. LPSERVER_INFO_102 psv102 = ToInfo;
  325. LPSERVER_INFO_402 psv402 = ToInfo;
  326. switch (ToLevel) {
  327. case 402 : /*FALLTHROUGH*/
  328. case 403 :
  329. psv402->sv402_ulist_mtime = psv2->sv2_ulist_mtime;
  330. psv402->sv402_glist_mtime = psv2->sv2_glist_mtime;
  331. psv402->sv402_alist_mtime = psv2->sv2_alist_mtime;
  332. NetpAssert(psv2->sv2_alerts != NULL); // avoid STRLEN err.
  333. CopyOK = NetpCopyStringToBuffer (
  334. psv2->sv2_alerts, // in string
  335. STRLEN(psv2->sv2_alerts), // input string length
  336. ToFixedEnd, // fixed data end
  337. & ToStringTop, // var area end (ptr updated)
  338. & psv402->sv402_alerts); // output string pointer
  339. NetpAssert(CopyOK);
  340. psv402->sv402_security = psv2->sv2_security;
  341. psv402->sv402_numadmin = psv2->sv2_numadmin;
  342. psv402->sv402_lanmask = psv2->sv2_lanmask;
  343. NetpAssert(psv2->sv2_guestacct != NULL); // Protect STRLEN.
  344. CopyOK = NetpCopyStringToBuffer (
  345. psv2->sv2_guestacct, // in string
  346. STRLEN(psv2->sv2_guestacct), // input string length
  347. ToFixedEnd, // fixed data end
  348. & ToStringTop, // var area end (ptr updated)
  349. & psv402->sv402_guestacct); // output string ptr
  350. NetpAssert(CopyOK);
  351. psv402->sv402_chdevs = psv2->sv2_chdevs;
  352. psv402->sv402_chdevq = psv2->sv2_chdevq;
  353. psv402->sv402_chdevjobs = psv2->sv2_chdevjobs;
  354. psv402->sv402_connections = psv2->sv2_connections;
  355. psv402->sv402_shares = psv2->sv2_shares;
  356. psv402->sv402_openfiles = psv2->sv2_openfiles;
  357. psv402->sv402_sessopens = psv2->sv2_sessopens;
  358. psv402->sv402_sessvcs = psv2->sv2_sessvcs;
  359. psv402->sv402_sessreqs = psv2->sv2_sessreqs;
  360. psv402->sv402_opensearch = psv2->sv2_opensearch;
  361. psv402->sv402_activelocks = psv2->sv2_activelocks;
  362. psv402->sv402_numreqbuf = psv2->sv2_numreqbuf;
  363. psv402->sv402_sizreqbuf = psv2->sv2_sizreqbuf;
  364. psv402->sv402_numbigbuf = psv2->sv2_numbigbuf;
  365. psv402->sv402_numfiletasks = psv2->sv2_numfiletasks;
  366. psv402->sv402_alertsched = psv2->sv2_alertsched;
  367. psv402->sv402_erroralert = psv2->sv2_erroralert;
  368. psv402->sv402_logonalert = psv2->sv2_logonalert;
  369. psv402->sv402_accessalert = psv2->sv2_accessalert;
  370. psv402->sv402_diskalert = psv2->sv2_diskalert;
  371. psv402->sv402_netioalert = psv2->sv2_netioalert;
  372. psv402->sv402_maxauditsz = psv2->sv2_maxauditsz;
  373. NetpAssert(psv2->sv2_srvheuristics != NULL); // Prot STRLEN.
  374. CopyOK = NetpCopyStringToBuffer (
  375. psv2->sv2_srvheuristics, // in string
  376. STRLEN(psv2->sv2_srvheuristics), // input str len
  377. ToFixedEnd, // fixed data end
  378. & ToStringTop, // var area end (ptr updated)
  379. & psv402->sv402_srvheuristics); // output str ptr
  380. NetpAssert(CopyOK);
  381. goto Done; // In nested switch, so "break" won't work.
  382. case 102 : // 2 to 102.
  383. // Set unique fields for levels 2 and 102.
  384. NetpAssert(ToLevel == 102);
  385. psv102->sv102_users = psv2->sv2_users;
  386. psv102->sv102_disc = psv2->sv2_disc;
  387. if (psv2->sv2_hidden == SV_HIDDEN) {;
  388. psv102->sv102_hidden = TRUE;
  389. } else {
  390. psv102->sv102_hidden = FALSE;
  391. }
  392. psv102->sv102_announce = psv2->sv2_announce;
  393. psv102->sv102_anndelta = psv2->sv2_anndelta;
  394. psv102->sv102_licenses = psv2->sv2_licenses;
  395. NetpAssert(psv2->sv2_userpath != NULL);
  396. CopyOK = NetpCopyStringToBuffer (
  397. psv2->sv2_userpath, // in string
  398. STRLEN(psv2->sv2_userpath), // input string length
  399. ToFixedEnd, // fixed data end
  400. & ToStringTop, // var area end (ptr updated)
  401. & psv102->sv102_userpath); // output string pointer
  402. NetpAssert(CopyOK);
  403. // Make sure it's OK to fall through to next level conv.
  404. CHECK_SERVER_OFFSETS( 1, 2, name);
  405. CHECK_SERVER_OFFSETS( 1, 2, version_major);
  406. CHECK_SERVER_OFFSETS( 1, 2, version_minor);
  407. CHECK_SERVER_OFFSETS( 1, 2, type);
  408. CHECK_SERVER_OFFSETS( 1, 2, comment);
  409. CHECK_SERVER_OFFSETS(101, 102, platform_id);
  410. CHECK_SERVER_OFFSETS(101, 102, name);
  411. CHECK_SERVER_OFFSETS(101, 102, version_major);
  412. CHECK_SERVER_OFFSETS(101, 102, version_minor);
  413. CHECK_SERVER_OFFSETS(101, 102, type);
  414. CHECK_SERVER_OFFSETS(101, 102, comment);
  415. break;
  416. default:
  417. NetpAssert( FALSE ); // Can't happen.
  418. }
  419. }
  420. /* FALLTHROUGH */
  421. case 1 :
  422. {
  423. DWORD CommentSize;
  424. LPSERVER_INFO_1 psv1 = FromInfo;
  425. LPSERVER_INFO_101 psv101 = ToInfo;
  426. psv101->sv101_version_major = psv1->sv1_version_major;
  427. psv101->sv101_version_minor = psv1->sv1_version_minor;
  428. psv101->sv101_type = psv1->sv1_type;
  429. // Copy comment string. Note that null ptr and ptr to null
  430. // char are both allowed here.
  431. if (psv1->sv1_comment != NULL) {
  432. CommentSize = STRLEN(psv1->sv1_comment);
  433. } else {
  434. CommentSize = 0;
  435. }
  436. CopyOK = NetpCopyStringToBuffer (
  437. psv1->sv1_comment, // in string
  438. CommentSize, // input string length
  439. ToFixedEnd, // fixed data end
  440. & ToStringTop, // var area end (ptr updated)
  441. & psv101->sv101_comment); // output string pointer
  442. NetpAssert(CopyOK);
  443. // Make sure it's OK to use level 0 => level 100 code.
  444. CHECK_SERVER_OFFSETS( 0, 1, name);
  445. CHECK_SERVER_OFFSETS(100, 101, name);
  446. CHECK_SERVER_OFFSETS(100, 101, platform_id);
  447. }
  448. /* FALLTHROUGH */
  449. case 0 :
  450. {
  451. LPSERVER_INFO_0 psv0 = FromInfo;
  452. LPSERVER_INFO_100 psv100 = ToInfo;
  453. if (FromLevel != 0) {
  454. LPSERVER_INFO_101 psv101 = ToInfo;
  455. if (psv101->sv101_type & SV_TYPE_NT) {
  456. psv100->sv100_platform_id = PLATFORM_ID_NT;
  457. } else {
  458. psv100->sv100_platform_id = PLATFORM_ID_OS2;
  459. }
  460. } else {
  461. psv100->sv100_platform_id = PLATFORM_ID_OS2;
  462. }
  463. NetpAssert(psv0->sv0_name != NULL); // or STRLEN() will fail.
  464. CopyOK = NetpCopyStringToBuffer (
  465. psv0->sv0_name, // in string
  466. STRLEN(psv0->sv0_name), // input string length
  467. ToFixedEnd, // fixed data end
  468. & ToStringTop, // var area end (ptr updated)
  469. & psv100->sv100_name); // output string pointer
  470. NetpAssert(CopyOK);
  471. break;
  472. }
  473. default :
  474. NetpKdPrint(( PREFIX_NETLIB
  475. "NetpConvertServerInfo: unexpected error.\n" ));
  476. return (NERR_InternalError);
  477. }
  478. Done:
  479. // Done converting.
  480. NetpAssert(ToInfo != NULL);
  481. NetpSetOptionalArg(ToStringTopPtr, ToStringTop);
  482. return (NERR_Success);
  483. } // NetpConvertServerInfo