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.

1004 lines
42 KiB

  1. /****************************************************************************/
  2. // sdqueryrpcfn.cpp
  3. //
  4. // TS Session Directory Query RPC server-side implementations.
  5. //
  6. // Copyright (C) 2000, Microsoft Corporation
  7. /****************************************************************************/
  8. #include "dis.h"
  9. #include "tssdshrd.h"
  10. #include "jetrpc.h"
  11. #include "jetsdis.h"
  12. #include "sdevent.h"
  13. #pragma warning (push, 4)
  14. #define TSSD_SERACH_MAX_RECORD 0xFFFFFFFF
  15. #define TSSD_NameLength 128
  16. extern PSID g_pAdminSid;
  17. /****************************************************************************/
  18. // SDQueryRPCAccessCheck
  19. //
  20. // Check if this SD Query RPC caller havs access right or not
  21. // Access is given only to administrator using ncalrpc protocol
  22. /****************************************************************************/
  23. RPC_STATUS RPC_ENTRY SDQueryRPCAccessCheck(RPC_IF_HANDLE idIF, void *Binding)
  24. {
  25. RPC_STATUS rpcStatus, rc;
  26. HANDLE hClientToken = NULL;
  27. DWORD Error;
  28. BOOL AccessStatus = FALSE;
  29. //RPC_AUTHZ_HANDLE hPrivs;
  30. //DWORD dwAuthn;
  31. idIF;
  32. if (NULL == g_pAdminSid) {
  33. goto HandleError;
  34. }
  35. // Check if the client uses the protocol sequence we expect
  36. if (!CheckRPCClientProtoSeq(Binding, L"ncalrpc")) {
  37. TSDISErrorOut(L"In SDQueryRPCAccessCheck: Client doesn't use the ncalrpc protocol sequence %u\n");
  38. goto HandleError;
  39. }
  40. // Check the access right of this rpc call
  41. rpcStatus = RpcImpersonateClient(Binding);
  42. if (RPC_S_OK != rpcStatus) {
  43. TSDISErrorOut(L"In SDQueryRPCAccessCheck: RpcImpersonateClient fail with %u\n", rpcStatus);
  44. goto HandleError;
  45. }
  46. // get our impersonated token
  47. if (!OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, FALSE, &hClientToken)) {
  48. Error = GetLastError();
  49. TSDISErrorOut(L"In SDQueryRPCAccessCheck: OpenThreadToken Error %u\n", Error);
  50. RpcRevertToSelf();
  51. goto HandleError;
  52. }
  53. RpcRevertToSelf();
  54. if (!CheckTokenMembership(hClientToken,
  55. g_pAdminSid,
  56. &AccessStatus)) {
  57. AccessStatus = FALSE;
  58. Error = GetLastError();
  59. TSDISErrorOut(L"In SDQueryRPCAccessCheck: CheckTokenMembership fails with %u\n", Error);
  60. }
  61. HandleError:
  62. if (AccessStatus) {
  63. rc = RPC_S_OK;
  64. }
  65. else {
  66. TSDISErrorOut(L"In SDQueryRPCAccessCheck: Unauthorized LPC call\n");
  67. rc = ERROR_ACCESS_DENIED;
  68. }
  69. if (hClientToken != NULL) {
  70. CloseHandle(hClientToken);
  71. }
  72. return rc;
  73. }
  74. // Query sessions for a username/domainname
  75. DWORD TSSDRpcQuerySessionInfoByUserName(
  76. /* [in] */ handle_t Binding,
  77. /* [in] */ WCHAR *UserName,
  78. /* [in] */ WCHAR *DomainName,
  79. /* [out] */ DWORD *pNumberOfSessions,
  80. /* [out] */ TSSD_SessionInfo __RPC_FAR __RPC_FAR **ppSessionInfo)
  81. {
  82. Binding;
  83. TSSD_SessionInfo *pSessionInfo = NULL;
  84. DWORD rc = (DWORD) E_FAIL;
  85. JET_SESID sesid = JET_sesidNil;
  86. JET_TABLEID servdirtableid;
  87. JET_TABLEID sessdirtableid;
  88. JET_DBID dbid;
  89. JET_ERR err;
  90. unsigned long cbActual;
  91. long ServerID;
  92. DWORD i;
  93. *pNumberOfSessions = 0;
  94. *ppSessionInfo = NULL;
  95. TRC1((TB,"TSSDRpcQuerySessionInfoByUserName: Query for user: %S\\%S", DomainName, UserName));
  96. CALL(JetBeginSession(g_instance, &sesid, "user", ""));
  97. CALL(JetOpenDatabase(sesid, JETDBFILENAME, "", &dbid, 0));
  98. CALL(JetOpenTable(sesid, dbid, "ServerDirectory", NULL, 0, 0,
  99. &servdirtableid));
  100. CALL(JetOpenTable(sesid, dbid, "SessionDirectory", NULL, 0, 0,
  101. &sessdirtableid));
  102. CALL(JetBeginTransaction(sesid));
  103. // search the session table for DomainName/UserName
  104. CALL(JetSetCurrentIndex(sesid, sessdirtableid, "AllSessionIndex"));
  105. CALL(JetMakeKey(sesid, sessdirtableid, UserName, (unsigned)
  106. (wcslen(UserName) + 1) * sizeof(WCHAR), JET_bitNewKey));
  107. CALL(JetMakeKey(sesid, sessdirtableid, DomainName, (unsigned)
  108. (wcslen(DomainName) + 1) * sizeof(WCHAR), 0));
  109. err = JetSeek(sesid, sessdirtableid, JET_bitSeekEQ | JET_bitSetIndexRange);
  110. if (err != JET_errSuccess) {
  111. TRC1((TB,"TSSDRpcQuerySessionInfoByUserName: Query for user: %S\\%S does not exist", DomainName, UserName));
  112. goto HandleError;
  113. }
  114. CALL(JetIndexRecordCount(sesid, sessdirtableid, pNumberOfSessions, TSSD_SERACH_MAX_RECORD));
  115. TRC1((TB, "Find %d session for this user", *pNumberOfSessions));
  116. *ppSessionInfo = (TSSD_SessionInfo *) MIDL_user_allocate(sizeof(TSSD_SessionInfo) *
  117. *pNumberOfSessions);
  118. pSessionInfo = *ppSessionInfo;
  119. if (pSessionInfo == NULL) {
  120. ERR((TB, "TSSDRpcQuerySessionInfoByUserName: Memory alloc failed!\n"));
  121. goto HandleError;
  122. }
  123. // retrieve the info for Sessions
  124. CALL(JetMove(sesid, sessdirtableid, JET_MoveFirst, 0));
  125. CALL(JetMakeKey(sesid, sessdirtableid, UserName, (unsigned)
  126. (wcslen(UserName) + 1) * sizeof(WCHAR), JET_bitNewKey));
  127. CALL(JetMakeKey(sesid, sessdirtableid, DomainName, (unsigned)
  128. (wcslen(DomainName) + 1) * sizeof(WCHAR), 0));
  129. CALL(JetSeek(sesid, sessdirtableid, JET_bitSeekEQ | JET_bitSetIndexRange));
  130. for (i=0; i<*pNumberOfSessions; i++) {
  131. CALL(JetRetrieveColumn(sesid, sessdirtableid, sesdircolumnid[
  132. SESSDIR_SERVERID_INTERNAL_INDEX], &ServerID,
  133. sizeof(ServerID), &cbActual, 0, NULL));
  134. CALL(JetRetrieveColumn(sesid, sessdirtableid, sesdircolumnid[
  135. SESSDIR_USERNAME_INTERNAL_INDEX], pSessionInfo[i].UserName,
  136. sizeof(pSessionInfo[i].UserName), &cbActual, 0, NULL));
  137. CALL(JetRetrieveColumn(sesid, sessdirtableid, sesdircolumnid[
  138. SESSDIR_DOMAIN_INTERNAL_INDEX], pSessionInfo[i].DomainName,
  139. sizeof(pSessionInfo[i].DomainName), &cbActual, 0, NULL));
  140. CALL(JetRetrieveColumn(sesid, sessdirtableid, sesdircolumnid[
  141. SESSDIR_SESSIONID_INTERNAL_INDEX], &(pSessionInfo[i].SessionID),
  142. sizeof(pSessionInfo[i].SessionID), &cbActual, 0, NULL));
  143. CALL(JetRetrieveColumn(sesid, sessdirtableid, sesdircolumnid[
  144. SESSDIR_TSPROTOCOL_INTERNAL_INDEX], &(pSessionInfo[i].TSProtocol),
  145. sizeof(pSessionInfo[i].TSProtocol), &cbActual, 0, NULL));
  146. CALL(JetRetrieveColumn(sesid, sessdirtableid, sesdircolumnid[
  147. SESSDIR_APPTYPE_INTERNAL_INDEX], pSessionInfo[i].ApplicationType,
  148. sizeof(pSessionInfo[i].ApplicationType), &cbActual, 0, NULL));
  149. CALL(JetRetrieveColumn(sesid, sessdirtableid, sesdircolumnid[
  150. SESSDIR_RESWIDTH_INTERNAL_INDEX], &(pSessionInfo[i].ResolutionWidth),
  151. sizeof(pSessionInfo[i].ResolutionWidth), &cbActual, 0, NULL));
  152. CALL(JetRetrieveColumn(sesid, sessdirtableid, sesdircolumnid[
  153. SESSDIR_RESHEIGHT_INTERNAL_INDEX], &(pSessionInfo[i].ResolutionHeight),
  154. sizeof(pSessionInfo[i].ResolutionHeight), &cbActual, 0, NULL));
  155. CALL(JetRetrieveColumn(sesid, sessdirtableid, sesdircolumnid[
  156. SESSDIR_COLORDEPTH_INTERNAL_INDEX], &(pSessionInfo[i].ColorDepth),
  157. sizeof(pSessionInfo[i].ColorDepth), &cbActual, 0, NULL));
  158. CALL(JetRetrieveColumn(sesid, sessdirtableid, sesdircolumnid[
  159. SESSDIR_STATE_INTERNAL_INDEX], &(pSessionInfo[i].SessionState),
  160. sizeof(pSessionInfo[i].SessionState), &cbActual, 0, NULL));
  161. CALL(JetRetrieveColumn(sesid, sessdirtableid, sesdircolumnid[
  162. SESSDIR_CTLOW_INTERNAL_INDEX], &(pSessionInfo[i].CreateTime.dwLowDateTime),
  163. sizeof(pSessionInfo[i].CreateTime.dwLowDateTime), &cbActual, 0, NULL));
  164. CALL(JetRetrieveColumn(sesid, sessdirtableid, sesdircolumnid[
  165. SESSDIR_CTHIGH_INTERNAL_INDEX], &(pSessionInfo[i].CreateTime.dwHighDateTime),
  166. sizeof(pSessionInfo[i].CreateTime.dwHighDateTime), &cbActual, 0, NULL));
  167. CALL(JetRetrieveColumn(sesid, sessdirtableid, sesdircolumnid[
  168. SESSDIR_DTLOW_INTERNAL_INDEX], &(pSessionInfo[i].DisconnectTime.dwLowDateTime),
  169. sizeof(pSessionInfo[i].DisconnectTime.dwLowDateTime), &cbActual, 0, NULL));
  170. CALL(JetRetrieveColumn(sesid, sessdirtableid, sesdircolumnid[
  171. SESSDIR_DTHIGH_INTERNAL_INDEX], &(pSessionInfo[i].DisconnectTime.dwHighDateTime),
  172. sizeof(pSessionInfo[i].DisconnectTime.dwHighDateTime), &cbActual, 0, NULL));
  173. // Find the cluster name the server belongs to
  174. CALL(JetMove(sesid, servdirtableid, JET_MoveFirst, 0));
  175. CALL(JetSetCurrentIndex(sesid, servdirtableid, "ServerIDIndex"));
  176. CALL(JetMakeKey(sesid, servdirtableid, (const void *)&ServerID, sizeof(ServerID),
  177. JET_bitNewKey));
  178. CALL(JetSeek(sesid, servdirtableid, JET_bitSeekEQ));
  179. CALL(JetRetrieveColumn(sesid, servdirtableid, servdircolumnid[
  180. SERVDIR_SERVDNSNAME_INTERNAL_INDEX], pSessionInfo[i].ServerName,
  181. sizeof(pSessionInfo[i].ServerName), &cbActual, 0, NULL));
  182. CALL(JetRetrieveColumn(sesid, servdirtableid, servdircolumnid[
  183. SERVDIR_SERVADDR_INTERNAL_INDEX], pSessionInfo[i].ServerIPAddress,
  184. sizeof(pSessionInfo[i].ServerIPAddress), &cbActual, 0, NULL));
  185. if (i != *pNumberOfSessions -1) {
  186. CALL(JetMove(sesid, sessdirtableid, JET_MoveNext, 0));
  187. }
  188. }
  189. CALL(JetCommitTransaction(sesid, 0));
  190. CALL(JetCloseTable(sesid, servdirtableid));
  191. CALL(JetCloseTable(sesid, sessdirtableid));
  192. CALL(JetCloseDatabase(sesid, dbid, 0));
  193. CALL(JetEndSession(sesid, 0));
  194. rc = (DWORD)RPC_S_OK;
  195. HandleError:
  196. if ((sesid != JET_sesidNil) && (rc != 0)) {
  197. // Force the session closed
  198. (VOID) JetEndSession(sesid, JET_bitForceSessionClosed);
  199. }
  200. return rc;
  201. }
  202. // Query for all sessions on a server
  203. DWORD TSSDRpcQuerySessionInfoByServer(
  204. /* [in] */ handle_t Binding,
  205. /* [in] */ WCHAR *ServerName,
  206. /* [out] */ DWORD *pNumberOfSessions,
  207. /* [out] */ TSSD_SessionInfo __RPC_FAR __RPC_FAR **ppSessionInfo)
  208. {
  209. Binding;
  210. TSSD_SessionInfo *pSessionInfo = NULL;
  211. DWORD rc = (DWORD) E_FAIL;
  212. JET_SESID sesid = JET_sesidNil;
  213. JET_TABLEID servdirtableid;
  214. JET_TABLEID sessdirtableid;
  215. JET_DBID dbid;
  216. JET_ERR err;
  217. unsigned long cbActual;
  218. long ServerID;
  219. WCHAR ServerIPAddress[TSSD_NameLength];
  220. DWORD i;
  221. *pNumberOfSessions = 0;
  222. *ppSessionInfo = NULL;
  223. TRC1((TB,"TSSDRpcQuerySessionInfoByServer: Query for servername %S", ServerName));
  224. CALL(JetBeginSession(g_instance, &sesid, "user", ""));
  225. CALL(JetOpenDatabase(sesid, JETDBFILENAME, "", &dbid, 0));
  226. CALL(JetOpenTable(sesid, dbid, "ServerDirectory", NULL, 0, 0,
  227. &servdirtableid));
  228. CALL(JetOpenTable(sesid, dbid, "SessionDirectory", NULL, 0, 0,
  229. &sessdirtableid));
  230. CALL(JetBeginTransaction(sesid));
  231. // search the server table by the ServerName for SeverID
  232. CALL(JetSetCurrentIndex(sesid, servdirtableid, "ServDNSNameIndex"));
  233. CALL(JetMakeKey(sesid, servdirtableid, ServerName, (unsigned)
  234. (wcslen(ServerName) + 1) * sizeof(WCHAR), JET_bitNewKey));
  235. err = JetSeek(sesid, servdirtableid, JET_bitSeekEQ);
  236. if (err != JET_errSuccess) {
  237. TRC1((TB,"TSSDRpcQuerySessionInfoByServer: Query for servername: %S does not exist", ServerName));
  238. goto HandleError;
  239. }
  240. CALL(JetRetrieveColumn(sesid, servdirtableid, servdircolumnid[
  241. SERVDIR_SERVID_INTERNAL_INDEX], &ServerID,
  242. sizeof(ServerID), &cbActual, 0, NULL));
  243. CALL(JetRetrieveColumn(sesid, servdirtableid, servdircolumnid[
  244. SERVDIR_SERVADDR_INTERNAL_INDEX], ServerIPAddress,
  245. sizeof(ServerIPAddress), &cbActual, 0, NULL));
  246. // search the sessions by this ServerID
  247. CALL(JetSetCurrentIndex(sesid, sessdirtableid, "ServerIndex"));
  248. CALL(JetMakeKey(sesid, sessdirtableid, &ServerID, sizeof(ServerID), JET_bitNewKey));
  249. err = JetSeek(sesid, sessdirtableid, JET_bitSeekEQ | JET_bitSetIndexRange);
  250. if (err != JET_errSuccess) {
  251. TRC1((TB,"TSSDRpcQuerySessionInfoByServer: Query for servername: %S does not have any session", ServerName));
  252. goto HandleError;
  253. }
  254. CALL(JetIndexRecordCount(sesid, sessdirtableid, pNumberOfSessions, TSSD_SERACH_MAX_RECORD));
  255. TRC1((TB, "Find %d session for this user", *pNumberOfSessions));
  256. *ppSessionInfo = (TSSD_SessionInfo *) MIDL_user_allocate(sizeof(TSSD_SessionInfo) *
  257. *pNumberOfSessions);
  258. pSessionInfo = *ppSessionInfo;
  259. if (pSessionInfo == NULL) {
  260. ERR((TB, "TSSDRpcQuerySessionInfoByServer: Memory alloc failed!\n"));
  261. goto HandleError;
  262. }
  263. // retrieve the info for Sessions
  264. CALL(JetMove(sesid, sessdirtableid, JET_MoveFirst, 0));
  265. CALL(JetSetCurrentIndex(sesid, sessdirtableid, "ServerIndex"));
  266. CALL(JetMakeKey(sesid, sessdirtableid, &ServerID, sizeof(ServerID), JET_bitNewKey));
  267. CALL(JetSeek(sesid, sessdirtableid, JET_bitSeekEQ | JET_bitSetIndexRange));
  268. for (i=0; i<*pNumberOfSessions; i++) {
  269. CALL(JetRetrieveColumn(sesid, sessdirtableid, sesdircolumnid[
  270. SESSDIR_SERVERID_INTERNAL_INDEX], &ServerID,
  271. sizeof(ServerID), &cbActual, 0, NULL));
  272. CALL(JetRetrieveColumn(sesid, sessdirtableid, sesdircolumnid[
  273. SESSDIR_USERNAME_INTERNAL_INDEX], pSessionInfo[i].UserName,
  274. sizeof(pSessionInfo[i].UserName), &cbActual, 0, NULL));
  275. CALL(JetRetrieveColumn(sesid, sessdirtableid, sesdircolumnid[
  276. SESSDIR_DOMAIN_INTERNAL_INDEX], pSessionInfo[i].DomainName,
  277. sizeof(pSessionInfo[i].DomainName), &cbActual, 0, NULL));
  278. CALL(JetRetrieveColumn(sesid, sessdirtableid, sesdircolumnid[
  279. SESSDIR_SESSIONID_INTERNAL_INDEX], &(pSessionInfo[i].SessionID),
  280. sizeof(pSessionInfo[i].SessionID), &cbActual, 0, NULL));
  281. CALL(JetRetrieveColumn(sesid, sessdirtableid, sesdircolumnid[
  282. SESSDIR_TSPROTOCOL_INTERNAL_INDEX], &(pSessionInfo[i].TSProtocol),
  283. sizeof(pSessionInfo[i].TSProtocol), &cbActual, 0, NULL));
  284. CALL(JetRetrieveColumn(sesid, sessdirtableid, sesdircolumnid[
  285. SESSDIR_APPTYPE_INTERNAL_INDEX], pSessionInfo[i].ApplicationType,
  286. sizeof(pSessionInfo[i].ApplicationType), &cbActual, 0, NULL));
  287. CALL(JetRetrieveColumn(sesid, sessdirtableid, sesdircolumnid[
  288. SESSDIR_RESWIDTH_INTERNAL_INDEX], &(pSessionInfo[i].ResolutionWidth),
  289. sizeof(pSessionInfo[i].ResolutionWidth), &cbActual, 0, NULL));
  290. CALL(JetRetrieveColumn(sesid, sessdirtableid, sesdircolumnid[
  291. SESSDIR_RESHEIGHT_INTERNAL_INDEX], &(pSessionInfo[i].ResolutionHeight),
  292. sizeof(pSessionInfo[i].ResolutionHeight), &cbActual, 0, NULL));
  293. CALL(JetRetrieveColumn(sesid, sessdirtableid, sesdircolumnid[
  294. SESSDIR_COLORDEPTH_INTERNAL_INDEX], &(pSessionInfo[i].ColorDepth),
  295. sizeof(pSessionInfo[i].ColorDepth), &cbActual, 0, NULL));
  296. CALL(JetRetrieveColumn(sesid, sessdirtableid, sesdircolumnid[
  297. SESSDIR_STATE_INTERNAL_INDEX], &(pSessionInfo[i].SessionState),
  298. sizeof(pSessionInfo[i].SessionState), &cbActual, 0, NULL));
  299. CALL(JetRetrieveColumn(sesid, sessdirtableid, sesdircolumnid[
  300. SESSDIR_CTLOW_INTERNAL_INDEX], &(pSessionInfo[i].CreateTime.dwLowDateTime),
  301. sizeof(pSessionInfo[i].CreateTime.dwLowDateTime), &cbActual, 0, NULL));
  302. CALL(JetRetrieveColumn(sesid, sessdirtableid, sesdircolumnid[
  303. SESSDIR_CTHIGH_INTERNAL_INDEX], &(pSessionInfo[i].CreateTime.dwHighDateTime),
  304. sizeof(pSessionInfo[i].CreateTime.dwHighDateTime), &cbActual, 0, NULL));
  305. CALL(JetRetrieveColumn(sesid, sessdirtableid, sesdircolumnid[
  306. SESSDIR_DTLOW_INTERNAL_INDEX], &(pSessionInfo[i].DisconnectTime.dwLowDateTime),
  307. sizeof(pSessionInfo[i].DisconnectTime.dwLowDateTime), &cbActual, 0, NULL));
  308. CALL(JetRetrieveColumn(sesid, sessdirtableid, sesdircolumnid[
  309. SESSDIR_DTHIGH_INTERNAL_INDEX], &(pSessionInfo[i].DisconnectTime.dwHighDateTime),
  310. sizeof(pSessionInfo[i].DisconnectTime.dwHighDateTime), &cbActual, 0, NULL));
  311. wcsncpy(pSessionInfo[i].ServerName, ServerName, TSSD_NameLength);
  312. (pSessionInfo[i].ServerName)[TSSD_NameLength -1] = L'\0';
  313. wcsncpy(pSessionInfo[i].ServerIPAddress, ServerIPAddress, TSSD_NameLength);
  314. (pSessionInfo[i].ServerIPAddress)[TSSD_NameLength -1] = L'\0';
  315. if (i != *pNumberOfSessions -1) {
  316. CALL(JetMove(sesid, sessdirtableid, JET_MoveNext, 0));
  317. }
  318. }
  319. CALL(JetCommitTransaction(sesid, 0));
  320. CALL(JetCloseTable(sesid, servdirtableid));
  321. CALL(JetCloseTable(sesid, sessdirtableid));
  322. CALL(JetCloseDatabase(sesid, dbid, 0));
  323. CALL(JetEndSession(sesid, 0));
  324. rc = (DWORD)RPC_S_OK;
  325. HandleError:
  326. if ((sesid != JET_sesidNil) && (rc != 0)) {
  327. // Force the session closed
  328. (VOID) JetEndSession(sesid, JET_bitForceSessionClosed);
  329. }
  330. return rc;
  331. }
  332. // Query the server info by server name
  333. DWORD TSSDRpcQueryServerByName(
  334. /* [in] */ handle_t Binding,
  335. /* [in] */ WCHAR *ServerName,
  336. /* [out] */ DWORD *pNumberOfServers,
  337. /* [out] */ TSSD_ServerInfo __RPC_FAR __RPC_FAR **ppServerInfo)
  338. {
  339. Binding;
  340. TSSD_ServerInfo *pServerInfo;
  341. DWORD rc = (DWORD) E_FAIL;
  342. JET_SESID sesid = JET_sesidNil;
  343. JET_TABLEID clusdirtableid;
  344. JET_TABLEID servdirtableid;
  345. JET_TABLEID sessdirtableid;
  346. JET_DBID dbid;
  347. JET_ERR err;
  348. unsigned long cbActual;
  349. long ServerID, ClusterID;
  350. *pNumberOfServers = 0;
  351. *ppServerInfo = NULL;
  352. pServerInfo = NULL;
  353. TRC1((TB,"TSSDRpcQueryServerByName: Query for Server Name: %S", ServerName));
  354. CALL(JetBeginSession(g_instance, &sesid, "user", ""));
  355. CALL(JetOpenDatabase(sesid, JETDBFILENAME, "", &dbid, 0));
  356. CALL(JetOpenTable(sesid, dbid, "ClusterDirectory", NULL, 0, 0,
  357. &clusdirtableid));
  358. CALL(JetOpenTable(sesid, dbid, "ServerDirectory", NULL, 0, 0,
  359. &servdirtableid));
  360. CALL(JetOpenTable(sesid, dbid, "SessionDirectory", NULL, 0, 0,
  361. &sessdirtableid));
  362. CALL(JetBeginTransaction(sesid));
  363. // search the server table for ServerName
  364. CALL(JetSetCurrentIndex(sesid, servdirtableid, "ServDNSNameIndex"));
  365. CALL(JetMakeKey(sesid, servdirtableid, ServerName, (unsigned)
  366. (wcslen(ServerName) + 1) * sizeof(WCHAR), JET_bitNewKey));
  367. err = JetSeek(sesid, servdirtableid, JET_bitSeekEQ);
  368. if (err != JET_errSuccess) {
  369. TRC1((TB,"TSSDRpcQueryServerByName: Query for servername: %S does not exist", ServerName));
  370. goto HandleError;
  371. }
  372. *pNumberOfServers = 1;
  373. *ppServerInfo = (TSSD_ServerInfo *) MIDL_user_allocate(sizeof(TSSD_ServerInfo) *
  374. *pNumberOfServers);
  375. pServerInfo = *ppServerInfo;
  376. if (pServerInfo == NULL) {
  377. ERR((TB, "TSSDRpcQueryServerByName: Memory alloc failed!\n"));
  378. goto HandleError;
  379. }
  380. // retrive the info for ServerInfo
  381. CALL(JetRetrieveColumn(sesid, servdirtableid, servdircolumnid[
  382. SERVDIR_SERVID_INTERNAL_INDEX], &ServerID,
  383. sizeof(ServerID), &cbActual, 0, NULL));
  384. CALL(JetRetrieveColumn(sesid, servdirtableid, servdircolumnid[
  385. SERVDIR_CLUSID_INTERNAL_INDEX], &ClusterID,
  386. sizeof(ClusterID), &cbActual, 0, NULL));
  387. CALL(JetRetrieveColumn(sesid, servdirtableid, servdircolumnid[
  388. SERVDIR_SERVDNSNAME_INTERNAL_INDEX], pServerInfo->ServerName,
  389. sizeof(pServerInfo->ServerName), &cbActual, 0, NULL));
  390. CALL(JetRetrieveColumn(sesid, servdirtableid, servdircolumnid[
  391. SERVDIR_SERVADDR_INTERNAL_INDEX], pServerInfo->ServerIPAddress,
  392. sizeof(pServerInfo->ServerIPAddress), &cbActual, 0, NULL));
  393. CALL(JetRetrieveColumn(sesid, servdirtableid, servdircolumnid[
  394. SERVDIR_SINGLESESS_INTERNAL_INDEX], &(pServerInfo->SingleSessionMode),
  395. sizeof(pServerInfo->SingleSessionMode), &cbActual, 0, NULL));
  396. // Find the session numbers in this server
  397. CALL(JetMove(sesid, sessdirtableid, JET_MoveFirst, 0));
  398. CALL(JetSetCurrentIndex(sesid, sessdirtableid, "ServerIndex"));
  399. CALL(JetMakeKey(sesid, sessdirtableid, (const void *)&ServerID, sizeof(ServerID),
  400. JET_bitNewKey));
  401. err = JetSeek(sesid, sessdirtableid, JET_bitSeekEQ | JET_bitSetIndexRange);
  402. if (JET_errSuccess == err) {
  403. CALL(JetIndexRecordCount(sesid, sessdirtableid, &(pServerInfo->NumberOfSessions), TSSD_SERACH_MAX_RECORD));
  404. }
  405. else {
  406. // This server doesn't have any session
  407. pServerInfo->NumberOfSessions = 0;
  408. }
  409. TRC1((TB,"TSSDRpcQueryServerByName: Get SessionNum is %d", pServerInfo->NumberOfSessions));
  410. // Find the cluster name the server belongs to
  411. CALL(JetMove(sesid, clusdirtableid, JET_MoveFirst, 0));
  412. CALL(JetSetCurrentIndex(sesid, clusdirtableid, "ClusIDIndex"));
  413. CALL(JetMakeKey(sesid, clusdirtableid, (const void *)&ClusterID, sizeof(ClusterID),
  414. JET_bitNewKey));
  415. CALL(JetSeek(sesid, clusdirtableid, JET_bitSeekEQ));
  416. CALL(JetRetrieveColumn(sesid, clusdirtableid, clusdircolumnid[
  417. CLUSDIR_CLUSNAME_INTERNAL_INDEX], pServerInfo->ClusterName,
  418. sizeof(pServerInfo->ClusterName), &cbActual, 0, NULL));
  419. TRC1((TB,"TSSDRpcQueryServerByName: Get ClusterName is %S", pServerInfo->ClusterName));
  420. CALL(JetCommitTransaction(sesid, 0));
  421. CALL(JetCloseTable(sesid, servdirtableid));
  422. CALL(JetCloseTable(sesid, clusdirtableid));
  423. CALL(JetCloseDatabase(sesid, dbid, 0));
  424. CALL(JetEndSession(sesid, 0));
  425. rc = (DWORD)RPC_S_OK;
  426. HandleError:
  427. if ((sesid != JET_sesidNil) && (rc != 0)) {
  428. // Force the session closed
  429. (VOID) JetEndSession(sesid, JET_bitForceSessionClosed);
  430. }
  431. return rc;
  432. }
  433. // Query info for all servers
  434. DWORD TSSDRpcQueryAllServers(
  435. /* [in] */ handle_t Binding,
  436. /* [out] */ DWORD *pNumberOfServers,
  437. /* [out] */ TSSD_ServerInfo __RPC_FAR __RPC_FAR **ppServerInfo)
  438. {
  439. Binding;
  440. TSSD_ServerInfo *pServerInfo;
  441. DWORD rc = (DWORD) E_FAIL;
  442. JET_SESID sesid = JET_sesidNil;
  443. JET_TABLEID clusdirtableid;
  444. JET_TABLEID servdirtableid;
  445. JET_TABLEID sessdirtableid;
  446. JET_DBID dbid;
  447. JET_ERR err;
  448. unsigned long cbActual;
  449. long ServerID, ClusterID;
  450. DWORD i;
  451. *pNumberOfServers = 0;
  452. *ppServerInfo = NULL;
  453. pServerInfo = NULL;
  454. TRC1((TB,"TSSDRpcQueryAllServers"));
  455. CALL(JetBeginSession(g_instance, &sesid, "user", ""));
  456. CALL(JetOpenDatabase(sesid, JETDBFILENAME, "", &dbid, 0));
  457. CALL(JetOpenTable(sesid, dbid, "ClusterDirectory", NULL, 0, 0,
  458. &clusdirtableid));
  459. CALL(JetOpenTable(sesid, dbid, "ServerDirectory", NULL, 0, 0,
  460. &servdirtableid));
  461. CALL(JetOpenTable(sesid, dbid, "SessionDirectory", NULL, 0, 0,
  462. &sessdirtableid));
  463. CALL(JetBeginTransaction(sesid));
  464. // Get the number of servers in server table
  465. err = JetMove(sesid, servdirtableid, JET_MoveFirst, 0);
  466. if (err != JET_errSuccess) {
  467. TRC1((TB,"TSSDRpcQueryAllServers: Session directory does not have any servers in it"));
  468. goto HandleError;
  469. }
  470. CALL(JetIndexRecordCount(sesid, servdirtableid, pNumberOfServers, TSSD_SERACH_MAX_RECORD));
  471. TRC1((TB, "Number of Servers found is %d", *pNumberOfServers));
  472. *ppServerInfo = (TSSD_ServerInfo *) MIDL_user_allocate(sizeof(TSSD_ServerInfo) *
  473. *pNumberOfServers);
  474. pServerInfo = *ppServerInfo;
  475. if (pServerInfo == NULL) {
  476. ERR((TB, "TSSDRpcQueryAllServers: Memory alloc failed!\n"));
  477. goto HandleError;
  478. }
  479. // Get all the servers
  480. CALL(JetMove(sesid, servdirtableid, JET_MoveFirst, 0));
  481. for (i=0; i<*pNumberOfServers; i++) {
  482. // retrive the info for ServerInfo
  483. CALL(JetRetrieveColumn(sesid, servdirtableid, servdircolumnid[
  484. SERVDIR_SERVID_INTERNAL_INDEX], &ServerID,
  485. sizeof(ServerID), &cbActual, 0, NULL));
  486. CALL(JetRetrieveColumn(sesid, servdirtableid, servdircolumnid[
  487. SERVDIR_CLUSID_INTERNAL_INDEX], &ClusterID,
  488. sizeof(ClusterID), &cbActual, 0, NULL));
  489. CALL(JetRetrieveColumn(sesid, servdirtableid, servdircolumnid[
  490. SERVDIR_SERVDNSNAME_INTERNAL_INDEX], pServerInfo[i].ServerName,
  491. sizeof(pServerInfo[i].ServerName), &cbActual, 0, NULL));
  492. CALL(JetRetrieveColumn(sesid, servdirtableid, servdircolumnid[
  493. SERVDIR_SERVADDR_INTERNAL_INDEX], pServerInfo[i].ServerIPAddress,
  494. sizeof(pServerInfo[i].ServerIPAddress), &cbActual, 0, NULL));
  495. CALL(JetRetrieveColumn(sesid, servdirtableid, servdircolumnid[
  496. SERVDIR_SINGLESESS_INTERNAL_INDEX], &(pServerInfo[i].SingleSessionMode),
  497. sizeof(pServerInfo[i].SingleSessionMode), &cbActual, 0, NULL));
  498. // Find the session numbers in this server
  499. err = JetMove(sesid, sessdirtableid, JET_MoveFirst, 0);
  500. if (JET_errSuccess == err) {
  501. CALL(JetSetCurrentIndex(sesid, sessdirtableid, "ServerIndex"));
  502. CALL(JetMakeKey(sesid, sessdirtableid, (const void *)&ServerID, sizeof(ServerID),
  503. JET_bitNewKey));
  504. err = JetSeek(sesid, sessdirtableid, JET_bitSeekEQ | JET_bitSetIndexRange);
  505. if (JET_errSuccess == err) {
  506. CALL(JetIndexRecordCount(sesid, sessdirtableid, &(pServerInfo[i].NumberOfSessions), TSSD_SERACH_MAX_RECORD));
  507. }
  508. else {
  509. // This server doens't have any session
  510. pServerInfo[i].NumberOfSessions = 0;
  511. }
  512. }
  513. else {
  514. // Session table is empty
  515. pServerInfo[i].NumberOfSessions = 0;
  516. }
  517. TRC1((TB,"TSSDRpcQueryServersInCluster: Get SessionNum is %d", pServerInfo[i].NumberOfSessions));
  518. // Find the cluster name the server belongs to
  519. CALL(JetMove(sesid, clusdirtableid, JET_MoveFirst, 0));
  520. CALL(JetSetCurrentIndex(sesid, clusdirtableid, "ClusIDIndex"));
  521. CALL(JetMakeKey(sesid, clusdirtableid, (const void *)&ClusterID, sizeof(ClusterID),
  522. JET_bitNewKey));
  523. CALL(JetSeek(sesid, clusdirtableid, JET_bitSeekEQ));
  524. CALL(JetRetrieveColumn(sesid, clusdirtableid, clusdircolumnid[
  525. CLUSDIR_CLUSNAME_INTERNAL_INDEX], pServerInfo[i].ClusterName,
  526. sizeof(pServerInfo[i].ClusterName), &cbActual, 0, NULL));
  527. if (i != *pNumberOfServers - 1) {
  528. CALL(JetMove(sesid, servdirtableid, JET_MoveNext, 0));
  529. }
  530. }
  531. CALL(JetCommitTransaction(sesid, 0));
  532. CALL(JetCloseTable(sesid, servdirtableid));
  533. CALL(JetCloseTable(sesid, clusdirtableid));
  534. CALL(JetCloseDatabase(sesid, dbid, 0));
  535. CALL(JetEndSession(sesid, 0));
  536. rc = (DWORD)RPC_S_OK;
  537. HandleError:
  538. if ((sesid != JET_sesidNil) && (rc != 0)) {
  539. // Force the session closed
  540. (VOID) JetEndSession(sesid, JET_bitForceSessionClosed);
  541. }
  542. return rc;
  543. }
  544. // Query all servers in the cluster by the cluster name
  545. DWORD TSSDRpcQueryServersInCluster(
  546. /* [in] */ handle_t Binding,
  547. /* [in] */ WCHAR *ClusterName,
  548. /* [out] */ DWORD *pNumberOfServers,
  549. /* [out] */ TSSD_ServerInfo __RPC_FAR __RPC_FAR **ppServerInfo)
  550. {
  551. Binding;
  552. TSSD_ServerInfo *pServerInfo;
  553. DWORD rc = (DWORD) E_FAIL;
  554. JET_SESID sesid = JET_sesidNil;
  555. JET_TABLEID clusdirtableid;
  556. JET_TABLEID servdirtableid;
  557. JET_TABLEID sessdirtableid;
  558. JET_DBID dbid;
  559. JET_ERR err;
  560. unsigned long cbActual;
  561. long ServerID, ClusterID;
  562. DWORD i;
  563. *pNumberOfServers = 0;
  564. *ppServerInfo = NULL;
  565. pServerInfo = NULL;
  566. TRC1((TB,"TSSDRpcQueryServersInCluster: Query for Cluster Name: %S", ClusterName));
  567. CALL(JetBeginSession(g_instance, &sesid, "user", ""));
  568. CALL(JetOpenDatabase(sesid, JETDBFILENAME, "", &dbid, 0));
  569. CALL(JetOpenTable(sesid, dbid, "ClusterDirectory", NULL, 0, 0,
  570. &clusdirtableid));
  571. CALL(JetOpenTable(sesid, dbid, "ServerDirectory", NULL, 0, 0,
  572. &servdirtableid));
  573. CALL(JetOpenTable(sesid, dbid, "SessionDirectory", NULL, 0, 0,
  574. &sessdirtableid));
  575. CALL(JetBeginTransaction(sesid));
  576. // search the cluster table for ClusterName
  577. CALL(JetSetCurrentIndex(sesid, clusdirtableid, "ClusNameIndex"));
  578. CALL(JetMakeKey(sesid, clusdirtableid, ClusterName, (unsigned)
  579. (wcslen(ClusterName) + 1) * sizeof(WCHAR), JET_bitNewKey));
  580. err = JetSeek(sesid, clusdirtableid, JET_bitSeekEQ);
  581. if (err != JET_errSuccess) {
  582. TRC1((TB,"TSSDRpcQueryServersInCluster: Clustername %S does not exist", ClusterName));
  583. goto HandleError;
  584. }
  585. CALL(JetRetrieveColumn(sesid, clusdirtableid, clusdircolumnid[
  586. CLUSDIR_CLUSID_INTERNAL_INDEX], &ClusterID,
  587. sizeof(ClusterID), &cbActual, 0, NULL));
  588. // search the server table for ClusterID
  589. CALL(JetSetCurrentIndex(sesid, servdirtableid, "ClusterIDIndex"));
  590. CALL(JetMakeKey(sesid, servdirtableid, &ClusterID, sizeof(ClusterID), JET_bitNewKey));
  591. CALL(JetSeek(sesid, servdirtableid, JET_bitSeekEQ | JET_bitSetIndexRange));
  592. CALL(JetIndexRecordCount(sesid, servdirtableid, pNumberOfServers, TSSD_SERACH_MAX_RECORD));
  593. TRC1((TB, "Number of Servers found is %d", *pNumberOfServers));
  594. *ppServerInfo = (TSSD_ServerInfo *) MIDL_user_allocate(sizeof(TSSD_ServerInfo) *
  595. *pNumberOfServers);
  596. pServerInfo = *ppServerInfo;
  597. if (pServerInfo == NULL) {
  598. ERR((TB, "TSSDRpcQueryServersInCluster: Memory alloc failed!\n"));
  599. goto HandleError;
  600. }
  601. // Get all the servers for this ClusterID
  602. CALL(JetMove(sesid, servdirtableid, JET_MoveFirst, 0));
  603. CALL(JetSetCurrentIndex(sesid, servdirtableid, "ClusterIDIndex"));
  604. CALL(JetMakeKey(sesid, servdirtableid, &ClusterID, sizeof(ClusterID), JET_bitNewKey));
  605. CALL(JetSeek(sesid, servdirtableid, JET_bitSeekEQ | JET_bitSetIndexRange));
  606. for (i=0; i<*pNumberOfServers; i++) {
  607. // retrive the info for ServerInfo
  608. CALL(JetRetrieveColumn(sesid, servdirtableid, servdircolumnid[
  609. SERVDIR_SERVID_INTERNAL_INDEX], &ServerID,
  610. sizeof(ServerID), &cbActual, 0, NULL));
  611. CALL(JetRetrieveColumn(sesid, servdirtableid, servdircolumnid[
  612. SERVDIR_SERVDNSNAME_INTERNAL_INDEX], pServerInfo[i].ServerName,
  613. sizeof(pServerInfo[i].ServerName), &cbActual, 0, NULL));
  614. CALL(JetRetrieveColumn(sesid, servdirtableid, servdircolumnid[
  615. SERVDIR_SERVADDR_INTERNAL_INDEX], pServerInfo[i].ServerIPAddress,
  616. sizeof(pServerInfo[i].ServerIPAddress), &cbActual, 0, NULL));
  617. CALL(JetRetrieveColumn(sesid, servdirtableid, servdircolumnid[
  618. SERVDIR_SINGLESESS_INTERNAL_INDEX], &(pServerInfo[i].SingleSessionMode),
  619. sizeof(pServerInfo[i].SingleSessionMode), &cbActual, 0, NULL));
  620. wcsncpy(pServerInfo[i].ClusterName, ClusterName, TSSD_NameLength);
  621. (pServerInfo[i].ClusterName)[TSSD_NameLength - 1] = L'\0';
  622. // Find the session numbers for this server
  623. err = JetMove(sesid, sessdirtableid, JET_MoveFirst, 0);
  624. if (JET_errSuccess == err) {
  625. CALL(JetSetCurrentIndex(sesid, sessdirtableid, "ServerIndex"));
  626. CALL(JetMakeKey(sesid, sessdirtableid, (const void *)&ServerID, sizeof(ServerID),
  627. JET_bitNewKey));
  628. err = JetSeek(sesid, sessdirtableid, JET_bitSeekEQ | JET_bitSetIndexRange);
  629. if (JET_errSuccess == err) {
  630. CALL(JetIndexRecordCount(sesid, sessdirtableid, &(pServerInfo[i].NumberOfSessions), TSSD_SERACH_MAX_RECORD));
  631. }
  632. else {
  633. // This server doesn't have any sessions
  634. pServerInfo[i].NumberOfSessions = 0;
  635. }
  636. TRC1((TB,"TSSDRpcQueryServersInCluster: Get SessionNum is %d", pServerInfo[i].NumberOfSessions));
  637. }
  638. else {
  639. // Session table is empty
  640. pServerInfo[i].NumberOfSessions = 0;
  641. }
  642. if (i != *pNumberOfServers - 1) {
  643. CALL(JetMove(sesid, servdirtableid, JET_MoveNext, 0));
  644. }
  645. }
  646. CALL(JetCommitTransaction(sesid, 0));
  647. CALL(JetCloseTable(sesid, servdirtableid));
  648. CALL(JetCloseTable(sesid, clusdirtableid));
  649. CALL(JetCloseDatabase(sesid, dbid, 0));
  650. CALL(JetEndSession(sesid, 0));
  651. rc = (DWORD)RPC_S_OK;
  652. HandleError:
  653. if ((sesid != JET_sesidNil) && (rc != 0)) {
  654. // Force the session closed
  655. (VOID) JetEndSession(sesid, JET_bitForceSessionClosed);
  656. }
  657. return rc;
  658. }
  659. // Query the info for all cluster
  660. DWORD TSSDRpcQueryAllClusterInfo(
  661. /* [in] */ handle_t Binding,
  662. /* [out] */ DWORD __RPC_FAR *pNumberOfClusters,
  663. /* [out] */ TSSD_ClusterInfo __RPC_FAR __RPC_FAR **ppClusterInfo)
  664. {
  665. Binding;
  666. pNumberOfClusters;
  667. TSSD_ClusterInfo *pClusterInfo;
  668. DWORD rc = (DWORD) E_FAIL;
  669. JET_SESID sesid = JET_sesidNil;
  670. JET_TABLEID clusdirtableid;
  671. JET_TABLEID servdirtableid;
  672. JET_DBID dbid;
  673. JET_ERR err;
  674. long *pClusterID = NULL;
  675. unsigned long cbActual;
  676. DWORD i;
  677. *pNumberOfClusters = 0;
  678. pClusterInfo = NULL;
  679. *ppClusterInfo = pClusterInfo;
  680. TRC1((TB,"TSSDRpcQueryAllClusterInfo"));
  681. CALL(JetBeginSession(g_instance, &sesid, "user", ""));
  682. CALL(JetOpenDatabase(sesid, JETDBFILENAME, "", &dbid, 0));
  683. CALL(JetOpenTable(sesid, dbid, "ClusterDirectory", NULL, 0, 0,
  684. &clusdirtableid));
  685. CALL(JetOpenTable(sesid, dbid, "ServerDirectory", NULL, 0, 0,
  686. &servdirtableid));
  687. CALL(JetBeginTransaction(sesid));
  688. // ClusterName is not specified
  689. // Get the ClusterID for all clusters
  690. err = JetMove(sesid, clusdirtableid, JET_MoveFirst, 0);
  691. if (err != JET_errSuccess) {
  692. TRC1((TB,"TSSDRpcQueryAllClusterInfo: Session Directory is empty"));
  693. goto HandleError;
  694. }
  695. CALL(JetIndexRecordCount(sesid, clusdirtableid, pNumberOfClusters, TSSD_SERACH_MAX_RECORD));
  696. pClusterID = (long *)LocalAlloc(LMEM_FIXED, *pNumberOfClusters * sizeof(long));
  697. if (pClusterID == NULL) {
  698. goto HandleError;
  699. }
  700. *ppClusterInfo = (TSSD_ClusterInfo *) MIDL_user_allocate(sizeof(TSSD_ClusterInfo) *
  701. *pNumberOfClusters);
  702. pClusterInfo = *ppClusterInfo;
  703. if (pClusterInfo == NULL) {
  704. TSDISErrorOut(L"TSSDRpcQueryClusterInfo: Memory alloc failed!\n");
  705. goto HandleError;
  706. }
  707. err = JetMove(sesid, clusdirtableid, JET_MoveFirst, 0);
  708. i = 0;
  709. while (err != JET_errNoCurrentRecord) {
  710. CALL(JetRetrieveColumn(sesid, clusdirtableid, clusdircolumnid[
  711. CLUSDIR_CLUSID_INTERNAL_INDEX], &pClusterID[i],
  712. sizeof(pClusterID[i]), &cbActual, 0, NULL));
  713. CALL(JetRetrieveColumn(sesid, clusdirtableid, clusdircolumnid[
  714. CLUSDIR_CLUSNAME_INTERNAL_INDEX], pClusterInfo[i].ClusterName,
  715. sizeof(pClusterInfo[i].ClusterName), &cbActual, 0, NULL));
  716. CALL(JetRetrieveColumn(sesid, clusdirtableid, clusdircolumnid[
  717. CLUSDIR_SINGLESESS_INTERNAL_INDEX], &(pClusterInfo[i].SingleSessionMode),
  718. sizeof(pClusterInfo[i].SingleSessionMode), &cbActual, 0, NULL));
  719. err = JetMove(sesid, clusdirtableid, JET_MoveNext, 0);
  720. i++;
  721. }
  722. // Find the server numbers in this cluster
  723. for (i=0; i<*pNumberOfClusters; i++) {
  724. CALL(JetMove(sesid, servdirtableid, JET_MoveFirst, 0));
  725. CALL(JetSetCurrentIndex(sesid, servdirtableid, "ClusterIDIndex"));
  726. CALL(JetMakeKey(sesid, servdirtableid, (const void *)&pClusterID[i], sizeof(pClusterID[i]),
  727. JET_bitNewKey));
  728. CALL(JetSeek(sesid, servdirtableid, JET_bitSeekEQ | JET_bitSetIndexRange));
  729. CALL(JetIndexRecordCount(sesid, servdirtableid, &(pClusterInfo[i].NumberOfServers), TSSD_SERACH_MAX_RECORD));
  730. TRC1((TB,"TSSDRpcQueryClusterInfo: Get ServerNum is %d", pClusterInfo[0].NumberOfServers));
  731. }
  732. CALL(JetCommitTransaction(sesid, 0));
  733. CALL(JetCloseTable(sesid, servdirtableid));
  734. CALL(JetCloseTable(sesid, clusdirtableid));
  735. CALL(JetCloseDatabase(sesid, dbid, 0));
  736. CALL(JetEndSession(sesid, 0));
  737. rc = (DWORD)RPC_S_OK;
  738. HandleError:
  739. // Deallocate memory
  740. if (pClusterID != NULL) {
  741. LocalFree(pClusterID);
  742. }
  743. if ((sesid != JET_sesidNil) && (rc != 0)) {
  744. // Force the session closed
  745. (VOID) JetEndSession(sesid, JET_bitForceSessionClosed);
  746. }
  747. return rc;
  748. }
  749. // Query the cluster info by the cluster name
  750. DWORD TSSDRpcQueryClusterInfo(
  751. /* [in] */ handle_t Binding,
  752. /*[in] */ WCHAR __RPC_FAR *ClusterName,
  753. /* [out] */ DWORD __RPC_FAR *pNumberOfClusters,
  754. /* [out] */ TSSD_ClusterInfo __RPC_FAR __RPC_FAR **ppClusterInfo)
  755. {
  756. Binding;
  757. TSSD_ClusterInfo *pClusterInfo;
  758. DWORD rc = (DWORD) E_FAIL;
  759. JET_SESID sesid = JET_sesidNil;
  760. JET_TABLEID clusdirtableid;
  761. JET_TABLEID servdirtableid;
  762. JET_DBID dbid;
  763. JET_ERR err;
  764. long *pClusterID = NULL;
  765. unsigned long cbActual;
  766. DWORD i;
  767. *pNumberOfClusters = 0;
  768. pClusterInfo = NULL;
  769. TRC1((TB,"Query for cluster Name: %S", ClusterName));
  770. CALL(JetBeginSession(g_instance, &sesid, "user", ""));
  771. CALL(JetOpenDatabase(sesid, JETDBFILENAME, "", &dbid, 0));
  772. CALL(JetOpenTable(sesid, dbid, "ClusterDirectory", NULL, 0, 0,
  773. &clusdirtableid));
  774. CALL(JetOpenTable(sesid, dbid, "ServerDirectory", NULL, 0, 0,
  775. &servdirtableid));
  776. CALL(JetBeginTransaction(sesid));
  777. // From the clustername find the clusterID
  778. CALL(JetSetCurrentIndex(sesid, clusdirtableid, "ClusNameIndex"));
  779. CALL(JetMakeKey(sesid, clusdirtableid, ClusterName, (unsigned)
  780. (wcslen(ClusterName) + 1) * sizeof(WCHAR), JET_bitNewKey));
  781. err = JetSeek(sesid, clusdirtableid, JET_bitSeekEQ);
  782. if (err != JET_errSuccess) {
  783. TRC1((TB,"TSSDRpcQueryClusterInfo: Clustername %S does not exist", ClusterName));
  784. goto HandleError;
  785. }
  786. *pNumberOfClusters = 1;
  787. pClusterID = (long *)LocalAlloc(LMEM_FIXED, *pNumberOfClusters * sizeof(long));
  788. if (pClusterID == NULL) {
  789. TSDISErrorOut(L"TSSDRpcQueryClusterInfo: Memory alloc failed!\n");
  790. goto HandleError;
  791. }
  792. *ppClusterInfo = (TSSD_ClusterInfo *) MIDL_user_allocate(sizeof(TSSD_ClusterInfo) *
  793. *pNumberOfClusters);
  794. pClusterInfo = *ppClusterInfo;
  795. if (pClusterInfo == NULL) {
  796. TSDISErrorOut(L"TSSDRpcQueryClusterInfo: Memory alloc failed!\n");
  797. goto HandleError;
  798. }
  799. CALL(JetRetrieveColumn(sesid, clusdirtableid, clusdircolumnid[
  800. CLUSDIR_CLUSID_INTERNAL_INDEX], &pClusterID[0],
  801. sizeof(pClusterID[0]), &cbActual, 0, NULL));
  802. CALL(JetRetrieveColumn(sesid, clusdirtableid, clusdircolumnid[
  803. CLUSDIR_CLUSNAME_INTERNAL_INDEX], pClusterInfo[0].ClusterName,
  804. sizeof(pClusterInfo[0].ClusterName), &cbActual, 0, NULL));
  805. TRC1((TB,"TSSDRpcQueryClusterInfo: Get cluster name %S", pClusterInfo[0].ClusterName));
  806. CALL(JetRetrieveColumn(sesid, clusdirtableid, clusdircolumnid[
  807. CLUSDIR_SINGLESESS_INTERNAL_INDEX], &(pClusterInfo[0].SingleSessionMode),
  808. sizeof(pClusterInfo[0].SingleSessionMode), &cbActual, 0, NULL));
  809. // Find the server numbers in this cluster
  810. for (i=0; i<*pNumberOfClusters; i++) {
  811. CALL(JetMove(sesid, servdirtableid, JET_MoveFirst, 0));
  812. CALL(JetSetCurrentIndex(sesid, servdirtableid, "ClusterIDIndex"));
  813. CALL(JetMakeKey(sesid, servdirtableid, (const void *)&pClusterID[i], sizeof(pClusterID[i]),
  814. JET_bitNewKey));
  815. CALL(JetSeek(sesid, servdirtableid, JET_bitSeekEQ | JET_bitSetIndexRange));
  816. CALL(JetIndexRecordCount(sesid, servdirtableid, &(pClusterInfo[i].NumberOfServers), TSSD_SERACH_MAX_RECORD));
  817. TRC1((TB,"TSSDRpcQueryClusterInfo: Get ServerNum is %d", pClusterInfo[i].NumberOfServers));
  818. }
  819. CALL(JetCommitTransaction(sesid, 0));
  820. CALL(JetCloseTable(sesid, servdirtableid));
  821. CALL(JetCloseTable(sesid, clusdirtableid));
  822. CALL(JetCloseDatabase(sesid, dbid, 0));
  823. CALL(JetEndSession(sesid, 0));
  824. rc = (DWORD)RPC_S_OK;
  825. HandleError:
  826. // Deallocate memory
  827. if (pClusterID != NULL) {
  828. LocalFree(pClusterID);
  829. }
  830. if ((sesid != JET_sesidNil) && (rc != 0)) {
  831. // Force the session closed
  832. (VOID) JetEndSession(sesid, JET_bitForceSessionClosed);
  833. }
  834. return rc;
  835. }
  836. #pragma warning (pop)