/****************************************************************************/ // sdqueryrpcfn.cpp // // TS Session Directory Query RPC server-side implementations. // // Copyright (C) 2000, Microsoft Corporation /****************************************************************************/ #include "dis.h" #include "tssdshrd.h" #include "jetrpc.h" #include "jetsdis.h" #include "sdevent.h" #pragma warning (push, 4) #define TSSD_SERACH_MAX_RECORD 0xFFFFFFFF #define TSSD_NameLength 128 extern PSID g_pAdminSid; /****************************************************************************/ // SDQueryRPCAccessCheck // // Check if this SD Query RPC caller havs access right or not // Access is given only to administrator using ncalrpc protocol /****************************************************************************/ RPC_STATUS RPC_ENTRY SDQueryRPCAccessCheck(RPC_IF_HANDLE idIF, void *Binding) { RPC_STATUS rpcStatus, rc; HANDLE hClientToken = NULL; DWORD Error; BOOL AccessStatus = FALSE; //RPC_AUTHZ_HANDLE hPrivs; //DWORD dwAuthn; idIF; if (NULL == g_pAdminSid) { goto HandleError; } // Check if the client uses the protocol sequence we expect if (!CheckRPCClientProtoSeq(Binding, L"ncalrpc")) { TSDISErrorOut(L"In SDQueryRPCAccessCheck: Client doesn't use the ncalrpc protocol sequence %u\n"); goto HandleError; } // Check the access right of this rpc call rpcStatus = RpcImpersonateClient(Binding); if (RPC_S_OK != rpcStatus) { TSDISErrorOut(L"In SDQueryRPCAccessCheck: RpcImpersonateClient fail with %u\n", rpcStatus); goto HandleError; } // get our impersonated token if (!OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, FALSE, &hClientToken)) { Error = GetLastError(); TSDISErrorOut(L"In SDQueryRPCAccessCheck: OpenThreadToken Error %u\n", Error); RpcRevertToSelf(); goto HandleError; } RpcRevertToSelf(); if (!CheckTokenMembership(hClientToken, g_pAdminSid, &AccessStatus)) { AccessStatus = FALSE; Error = GetLastError(); TSDISErrorOut(L"In SDQueryRPCAccessCheck: CheckTokenMembership fails with %u\n", Error); } HandleError: if (AccessStatus) { rc = RPC_S_OK; } else { TSDISErrorOut(L"In SDQueryRPCAccessCheck: Unauthorized LPC call\n"); rc = ERROR_ACCESS_DENIED; } if (hClientToken != NULL) { CloseHandle(hClientToken); } return rc; } // Query sessions for a username/domainname DWORD TSSDRpcQuerySessionInfoByUserName( /* [in] */ handle_t Binding, /* [in] */ WCHAR *UserName, /* [in] */ WCHAR *DomainName, /* [out] */ DWORD *pNumberOfSessions, /* [out] */ TSSD_SessionInfo __RPC_FAR __RPC_FAR **ppSessionInfo) { Binding; TSSD_SessionInfo *pSessionInfo = NULL; DWORD rc = (DWORD) E_FAIL; JET_SESID sesid = JET_sesidNil; JET_TABLEID servdirtableid; JET_TABLEID sessdirtableid; JET_DBID dbid; JET_ERR err; unsigned long cbActual; long ServerID; DWORD i; *pNumberOfSessions = 0; *ppSessionInfo = NULL; TRC1((TB,"TSSDRpcQuerySessionInfoByUserName: Query for user: %S\\%S", DomainName, UserName)); CALL(JetBeginSession(g_instance, &sesid, "user", "")); CALL(JetOpenDatabase(sesid, JETDBFILENAME, "", &dbid, 0)); CALL(JetOpenTable(sesid, dbid, "ServerDirectory", NULL, 0, 0, &servdirtableid)); CALL(JetOpenTable(sesid, dbid, "SessionDirectory", NULL, 0, 0, &sessdirtableid)); CALL(JetBeginTransaction(sesid)); // search the session table for DomainName/UserName CALL(JetSetCurrentIndex(sesid, sessdirtableid, "AllSessionIndex")); CALL(JetMakeKey(sesid, sessdirtableid, UserName, (unsigned) (wcslen(UserName) + 1) * sizeof(WCHAR), JET_bitNewKey)); CALL(JetMakeKey(sesid, sessdirtableid, DomainName, (unsigned) (wcslen(DomainName) + 1) * sizeof(WCHAR), 0)); err = JetSeek(sesid, sessdirtableid, JET_bitSeekEQ | JET_bitSetIndexRange); if (err != JET_errSuccess) { TRC1((TB,"TSSDRpcQuerySessionInfoByUserName: Query for user: %S\\%S does not exist", DomainName, UserName)); goto HandleError; } CALL(JetIndexRecordCount(sesid, sessdirtableid, pNumberOfSessions, TSSD_SERACH_MAX_RECORD)); TRC1((TB, "Find %d session for this user", *pNumberOfSessions)); *ppSessionInfo = (TSSD_SessionInfo *) MIDL_user_allocate(sizeof(TSSD_SessionInfo) * *pNumberOfSessions); pSessionInfo = *ppSessionInfo; if (pSessionInfo == NULL) { ERR((TB, "TSSDRpcQuerySessionInfoByUserName: Memory alloc failed!\n")); goto HandleError; } // retrieve the info for Sessions CALL(JetMove(sesid, sessdirtableid, JET_MoveFirst, 0)); CALL(JetMakeKey(sesid, sessdirtableid, UserName, (unsigned) (wcslen(UserName) + 1) * sizeof(WCHAR), JET_bitNewKey)); CALL(JetMakeKey(sesid, sessdirtableid, DomainName, (unsigned) (wcslen(DomainName) + 1) * sizeof(WCHAR), 0)); CALL(JetSeek(sesid, sessdirtableid, JET_bitSeekEQ | JET_bitSetIndexRange)); for (i=0; i<*pNumberOfSessions; i++) { CALL(JetRetrieveColumn(sesid, sessdirtableid, sesdircolumnid[ SESSDIR_SERVERID_INTERNAL_INDEX], &ServerID, sizeof(ServerID), &cbActual, 0, NULL)); CALL(JetRetrieveColumn(sesid, sessdirtableid, sesdircolumnid[ SESSDIR_USERNAME_INTERNAL_INDEX], pSessionInfo[i].UserName, sizeof(pSessionInfo[i].UserName), &cbActual, 0, NULL)); CALL(JetRetrieveColumn(sesid, sessdirtableid, sesdircolumnid[ SESSDIR_DOMAIN_INTERNAL_INDEX], pSessionInfo[i].DomainName, sizeof(pSessionInfo[i].DomainName), &cbActual, 0, NULL)); CALL(JetRetrieveColumn(sesid, sessdirtableid, sesdircolumnid[ SESSDIR_SESSIONID_INTERNAL_INDEX], &(pSessionInfo[i].SessionID), sizeof(pSessionInfo[i].SessionID), &cbActual, 0, NULL)); CALL(JetRetrieveColumn(sesid, sessdirtableid, sesdircolumnid[ SESSDIR_TSPROTOCOL_INTERNAL_INDEX], &(pSessionInfo[i].TSProtocol), sizeof(pSessionInfo[i].TSProtocol), &cbActual, 0, NULL)); CALL(JetRetrieveColumn(sesid, sessdirtableid, sesdircolumnid[ SESSDIR_APPTYPE_INTERNAL_INDEX], pSessionInfo[i].ApplicationType, sizeof(pSessionInfo[i].ApplicationType), &cbActual, 0, NULL)); CALL(JetRetrieveColumn(sesid, sessdirtableid, sesdircolumnid[ SESSDIR_RESWIDTH_INTERNAL_INDEX], &(pSessionInfo[i].ResolutionWidth), sizeof(pSessionInfo[i].ResolutionWidth), &cbActual, 0, NULL)); CALL(JetRetrieveColumn(sesid, sessdirtableid, sesdircolumnid[ SESSDIR_RESHEIGHT_INTERNAL_INDEX], &(pSessionInfo[i].ResolutionHeight), sizeof(pSessionInfo[i].ResolutionHeight), &cbActual, 0, NULL)); CALL(JetRetrieveColumn(sesid, sessdirtableid, sesdircolumnid[ SESSDIR_COLORDEPTH_INTERNAL_INDEX], &(pSessionInfo[i].ColorDepth), sizeof(pSessionInfo[i].ColorDepth), &cbActual, 0, NULL)); CALL(JetRetrieveColumn(sesid, sessdirtableid, sesdircolumnid[ SESSDIR_STATE_INTERNAL_INDEX], &(pSessionInfo[i].SessionState), sizeof(pSessionInfo[i].SessionState), &cbActual, 0, NULL)); CALL(JetRetrieveColumn(sesid, sessdirtableid, sesdircolumnid[ SESSDIR_CTLOW_INTERNAL_INDEX], &(pSessionInfo[i].CreateTime.dwLowDateTime), sizeof(pSessionInfo[i].CreateTime.dwLowDateTime), &cbActual, 0, NULL)); CALL(JetRetrieveColumn(sesid, sessdirtableid, sesdircolumnid[ SESSDIR_CTHIGH_INTERNAL_INDEX], &(pSessionInfo[i].CreateTime.dwHighDateTime), sizeof(pSessionInfo[i].CreateTime.dwHighDateTime), &cbActual, 0, NULL)); CALL(JetRetrieveColumn(sesid, sessdirtableid, sesdircolumnid[ SESSDIR_DTLOW_INTERNAL_INDEX], &(pSessionInfo[i].DisconnectTime.dwLowDateTime), sizeof(pSessionInfo[i].DisconnectTime.dwLowDateTime), &cbActual, 0, NULL)); CALL(JetRetrieveColumn(sesid, sessdirtableid, sesdircolumnid[ SESSDIR_DTHIGH_INTERNAL_INDEX], &(pSessionInfo[i].DisconnectTime.dwHighDateTime), sizeof(pSessionInfo[i].DisconnectTime.dwHighDateTime), &cbActual, 0, NULL)); // Find the cluster name the server belongs to CALL(JetMove(sesid, servdirtableid, JET_MoveFirst, 0)); CALL(JetSetCurrentIndex(sesid, servdirtableid, "ServerIDIndex")); CALL(JetMakeKey(sesid, servdirtableid, (const void *)&ServerID, sizeof(ServerID), JET_bitNewKey)); CALL(JetSeek(sesid, servdirtableid, JET_bitSeekEQ)); CALL(JetRetrieveColumn(sesid, servdirtableid, servdircolumnid[ SERVDIR_SERVDNSNAME_INTERNAL_INDEX], pSessionInfo[i].ServerName, sizeof(pSessionInfo[i].ServerName), &cbActual, 0, NULL)); CALL(JetRetrieveColumn(sesid, servdirtableid, servdircolumnid[ SERVDIR_SERVADDR_INTERNAL_INDEX], pSessionInfo[i].ServerIPAddress, sizeof(pSessionInfo[i].ServerIPAddress), &cbActual, 0, NULL)); if (i != *pNumberOfSessions -1) { CALL(JetMove(sesid, sessdirtableid, JET_MoveNext, 0)); } } CALL(JetCommitTransaction(sesid, 0)); CALL(JetCloseTable(sesid, servdirtableid)); CALL(JetCloseTable(sesid, sessdirtableid)); CALL(JetCloseDatabase(sesid, dbid, 0)); CALL(JetEndSession(sesid, 0)); rc = (DWORD)RPC_S_OK; HandleError: if ((sesid != JET_sesidNil) && (rc != 0)) { // Force the session closed (VOID) JetEndSession(sesid, JET_bitForceSessionClosed); } return rc; } // Query for all sessions on a server DWORD TSSDRpcQuerySessionInfoByServer( /* [in] */ handle_t Binding, /* [in] */ WCHAR *ServerName, /* [out] */ DWORD *pNumberOfSessions, /* [out] */ TSSD_SessionInfo __RPC_FAR __RPC_FAR **ppSessionInfo) { Binding; TSSD_SessionInfo *pSessionInfo = NULL; DWORD rc = (DWORD) E_FAIL; JET_SESID sesid = JET_sesidNil; JET_TABLEID servdirtableid; JET_TABLEID sessdirtableid; JET_DBID dbid; JET_ERR err; unsigned long cbActual; long ServerID; WCHAR ServerIPAddress[TSSD_NameLength]; DWORD i; *pNumberOfSessions = 0; *ppSessionInfo = NULL; TRC1((TB,"TSSDRpcQuerySessionInfoByServer: Query for servername %S", ServerName)); CALL(JetBeginSession(g_instance, &sesid, "user", "")); CALL(JetOpenDatabase(sesid, JETDBFILENAME, "", &dbid, 0)); CALL(JetOpenTable(sesid, dbid, "ServerDirectory", NULL, 0, 0, &servdirtableid)); CALL(JetOpenTable(sesid, dbid, "SessionDirectory", NULL, 0, 0, &sessdirtableid)); CALL(JetBeginTransaction(sesid)); // search the server table by the ServerName for SeverID CALL(JetSetCurrentIndex(sesid, servdirtableid, "ServDNSNameIndex")); CALL(JetMakeKey(sesid, servdirtableid, ServerName, (unsigned) (wcslen(ServerName) + 1) * sizeof(WCHAR), JET_bitNewKey)); err = JetSeek(sesid, servdirtableid, JET_bitSeekEQ); if (err != JET_errSuccess) { TRC1((TB,"TSSDRpcQuerySessionInfoByServer: Query for servername: %S does not exist", ServerName)); goto HandleError; } CALL(JetRetrieveColumn(sesid, servdirtableid, servdircolumnid[ SERVDIR_SERVID_INTERNAL_INDEX], &ServerID, sizeof(ServerID), &cbActual, 0, NULL)); CALL(JetRetrieveColumn(sesid, servdirtableid, servdircolumnid[ SERVDIR_SERVADDR_INTERNAL_INDEX], ServerIPAddress, sizeof(ServerIPAddress), &cbActual, 0, NULL)); // search the sessions by this ServerID CALL(JetSetCurrentIndex(sesid, sessdirtableid, "ServerIndex")); CALL(JetMakeKey(sesid, sessdirtableid, &ServerID, sizeof(ServerID), JET_bitNewKey)); err = JetSeek(sesid, sessdirtableid, JET_bitSeekEQ | JET_bitSetIndexRange); if (err != JET_errSuccess) { TRC1((TB,"TSSDRpcQuerySessionInfoByServer: Query for servername: %S does not have any session", ServerName)); goto HandleError; } CALL(JetIndexRecordCount(sesid, sessdirtableid, pNumberOfSessions, TSSD_SERACH_MAX_RECORD)); TRC1((TB, "Find %d session for this user", *pNumberOfSessions)); *ppSessionInfo = (TSSD_SessionInfo *) MIDL_user_allocate(sizeof(TSSD_SessionInfo) * *pNumberOfSessions); pSessionInfo = *ppSessionInfo; if (pSessionInfo == NULL) { ERR((TB, "TSSDRpcQuerySessionInfoByServer: Memory alloc failed!\n")); goto HandleError; } // retrieve the info for Sessions CALL(JetMove(sesid, sessdirtableid, JET_MoveFirst, 0)); CALL(JetSetCurrentIndex(sesid, sessdirtableid, "ServerIndex")); CALL(JetMakeKey(sesid, sessdirtableid, &ServerID, sizeof(ServerID), JET_bitNewKey)); CALL(JetSeek(sesid, sessdirtableid, JET_bitSeekEQ | JET_bitSetIndexRange)); for (i=0; i<*pNumberOfSessions; i++) { CALL(JetRetrieveColumn(sesid, sessdirtableid, sesdircolumnid[ SESSDIR_SERVERID_INTERNAL_INDEX], &ServerID, sizeof(ServerID), &cbActual, 0, NULL)); CALL(JetRetrieveColumn(sesid, sessdirtableid, sesdircolumnid[ SESSDIR_USERNAME_INTERNAL_INDEX], pSessionInfo[i].UserName, sizeof(pSessionInfo[i].UserName), &cbActual, 0, NULL)); CALL(JetRetrieveColumn(sesid, sessdirtableid, sesdircolumnid[ SESSDIR_DOMAIN_INTERNAL_INDEX], pSessionInfo[i].DomainName, sizeof(pSessionInfo[i].DomainName), &cbActual, 0, NULL)); CALL(JetRetrieveColumn(sesid, sessdirtableid, sesdircolumnid[ SESSDIR_SESSIONID_INTERNAL_INDEX], &(pSessionInfo[i].SessionID), sizeof(pSessionInfo[i].SessionID), &cbActual, 0, NULL)); CALL(JetRetrieveColumn(sesid, sessdirtableid, sesdircolumnid[ SESSDIR_TSPROTOCOL_INTERNAL_INDEX], &(pSessionInfo[i].TSProtocol), sizeof(pSessionInfo[i].TSProtocol), &cbActual, 0, NULL)); CALL(JetRetrieveColumn(sesid, sessdirtableid, sesdircolumnid[ SESSDIR_APPTYPE_INTERNAL_INDEX], pSessionInfo[i].ApplicationType, sizeof(pSessionInfo[i].ApplicationType), &cbActual, 0, NULL)); CALL(JetRetrieveColumn(sesid, sessdirtableid, sesdircolumnid[ SESSDIR_RESWIDTH_INTERNAL_INDEX], &(pSessionInfo[i].ResolutionWidth), sizeof(pSessionInfo[i].ResolutionWidth), &cbActual, 0, NULL)); CALL(JetRetrieveColumn(sesid, sessdirtableid, sesdircolumnid[ SESSDIR_RESHEIGHT_INTERNAL_INDEX], &(pSessionInfo[i].ResolutionHeight), sizeof(pSessionInfo[i].ResolutionHeight), &cbActual, 0, NULL)); CALL(JetRetrieveColumn(sesid, sessdirtableid, sesdircolumnid[ SESSDIR_COLORDEPTH_INTERNAL_INDEX], &(pSessionInfo[i].ColorDepth), sizeof(pSessionInfo[i].ColorDepth), &cbActual, 0, NULL)); CALL(JetRetrieveColumn(sesid, sessdirtableid, sesdircolumnid[ SESSDIR_STATE_INTERNAL_INDEX], &(pSessionInfo[i].SessionState), sizeof(pSessionInfo[i].SessionState), &cbActual, 0, NULL)); CALL(JetRetrieveColumn(sesid, sessdirtableid, sesdircolumnid[ SESSDIR_CTLOW_INTERNAL_INDEX], &(pSessionInfo[i].CreateTime.dwLowDateTime), sizeof(pSessionInfo[i].CreateTime.dwLowDateTime), &cbActual, 0, NULL)); CALL(JetRetrieveColumn(sesid, sessdirtableid, sesdircolumnid[ SESSDIR_CTHIGH_INTERNAL_INDEX], &(pSessionInfo[i].CreateTime.dwHighDateTime), sizeof(pSessionInfo[i].CreateTime.dwHighDateTime), &cbActual, 0, NULL)); CALL(JetRetrieveColumn(sesid, sessdirtableid, sesdircolumnid[ SESSDIR_DTLOW_INTERNAL_INDEX], &(pSessionInfo[i].DisconnectTime.dwLowDateTime), sizeof(pSessionInfo[i].DisconnectTime.dwLowDateTime), &cbActual, 0, NULL)); CALL(JetRetrieveColumn(sesid, sessdirtableid, sesdircolumnid[ SESSDIR_DTHIGH_INTERNAL_INDEX], &(pSessionInfo[i].DisconnectTime.dwHighDateTime), sizeof(pSessionInfo[i].DisconnectTime.dwHighDateTime), &cbActual, 0, NULL)); wcsncpy(pSessionInfo[i].ServerName, ServerName, TSSD_NameLength); (pSessionInfo[i].ServerName)[TSSD_NameLength -1] = L'\0'; wcsncpy(pSessionInfo[i].ServerIPAddress, ServerIPAddress, TSSD_NameLength); (pSessionInfo[i].ServerIPAddress)[TSSD_NameLength -1] = L'\0'; if (i != *pNumberOfSessions -1) { CALL(JetMove(sesid, sessdirtableid, JET_MoveNext, 0)); } } CALL(JetCommitTransaction(sesid, 0)); CALL(JetCloseTable(sesid, servdirtableid)); CALL(JetCloseTable(sesid, sessdirtableid)); CALL(JetCloseDatabase(sesid, dbid, 0)); CALL(JetEndSession(sesid, 0)); rc = (DWORD)RPC_S_OK; HandleError: if ((sesid != JET_sesidNil) && (rc != 0)) { // Force the session closed (VOID) JetEndSession(sesid, JET_bitForceSessionClosed); } return rc; } // Query the server info by server name DWORD TSSDRpcQueryServerByName( /* [in] */ handle_t Binding, /* [in] */ WCHAR *ServerName, /* [out] */ DWORD *pNumberOfServers, /* [out] */ TSSD_ServerInfo __RPC_FAR __RPC_FAR **ppServerInfo) { Binding; TSSD_ServerInfo *pServerInfo; DWORD rc = (DWORD) E_FAIL; JET_SESID sesid = JET_sesidNil; JET_TABLEID clusdirtableid; JET_TABLEID servdirtableid; JET_TABLEID sessdirtableid; JET_DBID dbid; JET_ERR err; unsigned long cbActual; long ServerID, ClusterID; *pNumberOfServers = 0; *ppServerInfo = NULL; pServerInfo = NULL; TRC1((TB,"TSSDRpcQueryServerByName: Query for Server Name: %S", ServerName)); CALL(JetBeginSession(g_instance, &sesid, "user", "")); CALL(JetOpenDatabase(sesid, JETDBFILENAME, "", &dbid, 0)); CALL(JetOpenTable(sesid, dbid, "ClusterDirectory", NULL, 0, 0, &clusdirtableid)); CALL(JetOpenTable(sesid, dbid, "ServerDirectory", NULL, 0, 0, &servdirtableid)); CALL(JetOpenTable(sesid, dbid, "SessionDirectory", NULL, 0, 0, &sessdirtableid)); CALL(JetBeginTransaction(sesid)); // search the server table for ServerName CALL(JetSetCurrentIndex(sesid, servdirtableid, "ServDNSNameIndex")); CALL(JetMakeKey(sesid, servdirtableid, ServerName, (unsigned) (wcslen(ServerName) + 1) * sizeof(WCHAR), JET_bitNewKey)); err = JetSeek(sesid, servdirtableid, JET_bitSeekEQ); if (err != JET_errSuccess) { TRC1((TB,"TSSDRpcQueryServerByName: Query for servername: %S does not exist", ServerName)); goto HandleError; } *pNumberOfServers = 1; *ppServerInfo = (TSSD_ServerInfo *) MIDL_user_allocate(sizeof(TSSD_ServerInfo) * *pNumberOfServers); pServerInfo = *ppServerInfo; if (pServerInfo == NULL) { ERR((TB, "TSSDRpcQueryServerByName: Memory alloc failed!\n")); goto HandleError; } // retrive the info for ServerInfo CALL(JetRetrieveColumn(sesid, servdirtableid, servdircolumnid[ SERVDIR_SERVID_INTERNAL_INDEX], &ServerID, sizeof(ServerID), &cbActual, 0, NULL)); CALL(JetRetrieveColumn(sesid, servdirtableid, servdircolumnid[ SERVDIR_CLUSID_INTERNAL_INDEX], &ClusterID, sizeof(ClusterID), &cbActual, 0, NULL)); CALL(JetRetrieveColumn(sesid, servdirtableid, servdircolumnid[ SERVDIR_SERVDNSNAME_INTERNAL_INDEX], pServerInfo->ServerName, sizeof(pServerInfo->ServerName), &cbActual, 0, NULL)); CALL(JetRetrieveColumn(sesid, servdirtableid, servdircolumnid[ SERVDIR_SERVADDR_INTERNAL_INDEX], pServerInfo->ServerIPAddress, sizeof(pServerInfo->ServerIPAddress), &cbActual, 0, NULL)); CALL(JetRetrieveColumn(sesid, servdirtableid, servdircolumnid[ SERVDIR_SINGLESESS_INTERNAL_INDEX], &(pServerInfo->SingleSessionMode), sizeof(pServerInfo->SingleSessionMode), &cbActual, 0, NULL)); // Find the session numbers in this server CALL(JetMove(sesid, sessdirtableid, JET_MoveFirst, 0)); CALL(JetSetCurrentIndex(sesid, sessdirtableid, "ServerIndex")); CALL(JetMakeKey(sesid, sessdirtableid, (const void *)&ServerID, sizeof(ServerID), JET_bitNewKey)); err = JetSeek(sesid, sessdirtableid, JET_bitSeekEQ | JET_bitSetIndexRange); if (JET_errSuccess == err) { CALL(JetIndexRecordCount(sesid, sessdirtableid, &(pServerInfo->NumberOfSessions), TSSD_SERACH_MAX_RECORD)); } else { // This server doesn't have any session pServerInfo->NumberOfSessions = 0; } TRC1((TB,"TSSDRpcQueryServerByName: Get SessionNum is %d", pServerInfo->NumberOfSessions)); // Find the cluster name the server belongs to CALL(JetMove(sesid, clusdirtableid, JET_MoveFirst, 0)); CALL(JetSetCurrentIndex(sesid, clusdirtableid, "ClusIDIndex")); CALL(JetMakeKey(sesid, clusdirtableid, (const void *)&ClusterID, sizeof(ClusterID), JET_bitNewKey)); CALL(JetSeek(sesid, clusdirtableid, JET_bitSeekEQ)); CALL(JetRetrieveColumn(sesid, clusdirtableid, clusdircolumnid[ CLUSDIR_CLUSNAME_INTERNAL_INDEX], pServerInfo->ClusterName, sizeof(pServerInfo->ClusterName), &cbActual, 0, NULL)); TRC1((TB,"TSSDRpcQueryServerByName: Get ClusterName is %S", pServerInfo->ClusterName)); CALL(JetCommitTransaction(sesid, 0)); CALL(JetCloseTable(sesid, servdirtableid)); CALL(JetCloseTable(sesid, clusdirtableid)); CALL(JetCloseDatabase(sesid, dbid, 0)); CALL(JetEndSession(sesid, 0)); rc = (DWORD)RPC_S_OK; HandleError: if ((sesid != JET_sesidNil) && (rc != 0)) { // Force the session closed (VOID) JetEndSession(sesid, JET_bitForceSessionClosed); } return rc; } // Query info for all servers DWORD TSSDRpcQueryAllServers( /* [in] */ handle_t Binding, /* [out] */ DWORD *pNumberOfServers, /* [out] */ TSSD_ServerInfo __RPC_FAR __RPC_FAR **ppServerInfo) { Binding; TSSD_ServerInfo *pServerInfo; DWORD rc = (DWORD) E_FAIL; JET_SESID sesid = JET_sesidNil; JET_TABLEID clusdirtableid; JET_TABLEID servdirtableid; JET_TABLEID sessdirtableid; JET_DBID dbid; JET_ERR err; unsigned long cbActual; long ServerID, ClusterID; DWORD i; *pNumberOfServers = 0; *ppServerInfo = NULL; pServerInfo = NULL; TRC1((TB,"TSSDRpcQueryAllServers")); CALL(JetBeginSession(g_instance, &sesid, "user", "")); CALL(JetOpenDatabase(sesid, JETDBFILENAME, "", &dbid, 0)); CALL(JetOpenTable(sesid, dbid, "ClusterDirectory", NULL, 0, 0, &clusdirtableid)); CALL(JetOpenTable(sesid, dbid, "ServerDirectory", NULL, 0, 0, &servdirtableid)); CALL(JetOpenTable(sesid, dbid, "SessionDirectory", NULL, 0, 0, &sessdirtableid)); CALL(JetBeginTransaction(sesid)); // Get the number of servers in server table err = JetMove(sesid, servdirtableid, JET_MoveFirst, 0); if (err != JET_errSuccess) { TRC1((TB,"TSSDRpcQueryAllServers: Session directory does not have any servers in it")); goto HandleError; } CALL(JetIndexRecordCount(sesid, servdirtableid, pNumberOfServers, TSSD_SERACH_MAX_RECORD)); TRC1((TB, "Number of Servers found is %d", *pNumberOfServers)); *ppServerInfo = (TSSD_ServerInfo *) MIDL_user_allocate(sizeof(TSSD_ServerInfo) * *pNumberOfServers); pServerInfo = *ppServerInfo; if (pServerInfo == NULL) { ERR((TB, "TSSDRpcQueryAllServers: Memory alloc failed!\n")); goto HandleError; } // Get all the servers CALL(JetMove(sesid, servdirtableid, JET_MoveFirst, 0)); for (i=0; i<*pNumberOfServers; i++) { // retrive the info for ServerInfo CALL(JetRetrieveColumn(sesid, servdirtableid, servdircolumnid[ SERVDIR_SERVID_INTERNAL_INDEX], &ServerID, sizeof(ServerID), &cbActual, 0, NULL)); CALL(JetRetrieveColumn(sesid, servdirtableid, servdircolumnid[ SERVDIR_CLUSID_INTERNAL_INDEX], &ClusterID, sizeof(ClusterID), &cbActual, 0, NULL)); CALL(JetRetrieveColumn(sesid, servdirtableid, servdircolumnid[ SERVDIR_SERVDNSNAME_INTERNAL_INDEX], pServerInfo[i].ServerName, sizeof(pServerInfo[i].ServerName), &cbActual, 0, NULL)); CALL(JetRetrieveColumn(sesid, servdirtableid, servdircolumnid[ SERVDIR_SERVADDR_INTERNAL_INDEX], pServerInfo[i].ServerIPAddress, sizeof(pServerInfo[i].ServerIPAddress), &cbActual, 0, NULL)); CALL(JetRetrieveColumn(sesid, servdirtableid, servdircolumnid[ SERVDIR_SINGLESESS_INTERNAL_INDEX], &(pServerInfo[i].SingleSessionMode), sizeof(pServerInfo[i].SingleSessionMode), &cbActual, 0, NULL)); // Find the session numbers in this server err = JetMove(sesid, sessdirtableid, JET_MoveFirst, 0); if (JET_errSuccess == err) { CALL(JetSetCurrentIndex(sesid, sessdirtableid, "ServerIndex")); CALL(JetMakeKey(sesid, sessdirtableid, (const void *)&ServerID, sizeof(ServerID), JET_bitNewKey)); err = JetSeek(sesid, sessdirtableid, JET_bitSeekEQ | JET_bitSetIndexRange); if (JET_errSuccess == err) { CALL(JetIndexRecordCount(sesid, sessdirtableid, &(pServerInfo[i].NumberOfSessions), TSSD_SERACH_MAX_RECORD)); } else { // This server doens't have any session pServerInfo[i].NumberOfSessions = 0; } } else { // Session table is empty pServerInfo[i].NumberOfSessions = 0; } TRC1((TB,"TSSDRpcQueryServersInCluster: Get SessionNum is %d", pServerInfo[i].NumberOfSessions)); // Find the cluster name the server belongs to CALL(JetMove(sesid, clusdirtableid, JET_MoveFirst, 0)); CALL(JetSetCurrentIndex(sesid, clusdirtableid, "ClusIDIndex")); CALL(JetMakeKey(sesid, clusdirtableid, (const void *)&ClusterID, sizeof(ClusterID), JET_bitNewKey)); CALL(JetSeek(sesid, clusdirtableid, JET_bitSeekEQ)); CALL(JetRetrieveColumn(sesid, clusdirtableid, clusdircolumnid[ CLUSDIR_CLUSNAME_INTERNAL_INDEX], pServerInfo[i].ClusterName, sizeof(pServerInfo[i].ClusterName), &cbActual, 0, NULL)); if (i != *pNumberOfServers - 1) { CALL(JetMove(sesid, servdirtableid, JET_MoveNext, 0)); } } CALL(JetCommitTransaction(sesid, 0)); CALL(JetCloseTable(sesid, servdirtableid)); CALL(JetCloseTable(sesid, clusdirtableid)); CALL(JetCloseDatabase(sesid, dbid, 0)); CALL(JetEndSession(sesid, 0)); rc = (DWORD)RPC_S_OK; HandleError: if ((sesid != JET_sesidNil) && (rc != 0)) { // Force the session closed (VOID) JetEndSession(sesid, JET_bitForceSessionClosed); } return rc; } // Query all servers in the cluster by the cluster name DWORD TSSDRpcQueryServersInCluster( /* [in] */ handle_t Binding, /* [in] */ WCHAR *ClusterName, /* [out] */ DWORD *pNumberOfServers, /* [out] */ TSSD_ServerInfo __RPC_FAR __RPC_FAR **ppServerInfo) { Binding; TSSD_ServerInfo *pServerInfo; DWORD rc = (DWORD) E_FAIL; JET_SESID sesid = JET_sesidNil; JET_TABLEID clusdirtableid; JET_TABLEID servdirtableid; JET_TABLEID sessdirtableid; JET_DBID dbid; JET_ERR err; unsigned long cbActual; long ServerID, ClusterID; DWORD i; *pNumberOfServers = 0; *ppServerInfo = NULL; pServerInfo = NULL; TRC1((TB,"TSSDRpcQueryServersInCluster: Query for Cluster Name: %S", ClusterName)); CALL(JetBeginSession(g_instance, &sesid, "user", "")); CALL(JetOpenDatabase(sesid, JETDBFILENAME, "", &dbid, 0)); CALL(JetOpenTable(sesid, dbid, "ClusterDirectory", NULL, 0, 0, &clusdirtableid)); CALL(JetOpenTable(sesid, dbid, "ServerDirectory", NULL, 0, 0, &servdirtableid)); CALL(JetOpenTable(sesid, dbid, "SessionDirectory", NULL, 0, 0, &sessdirtableid)); CALL(JetBeginTransaction(sesid)); // search the cluster table for ClusterName CALL(JetSetCurrentIndex(sesid, clusdirtableid, "ClusNameIndex")); CALL(JetMakeKey(sesid, clusdirtableid, ClusterName, (unsigned) (wcslen(ClusterName) + 1) * sizeof(WCHAR), JET_bitNewKey)); err = JetSeek(sesid, clusdirtableid, JET_bitSeekEQ); if (err != JET_errSuccess) { TRC1((TB,"TSSDRpcQueryServersInCluster: Clustername %S does not exist", ClusterName)); goto HandleError; } CALL(JetRetrieveColumn(sesid, clusdirtableid, clusdircolumnid[ CLUSDIR_CLUSID_INTERNAL_INDEX], &ClusterID, sizeof(ClusterID), &cbActual, 0, NULL)); // search the server table for ClusterID CALL(JetSetCurrentIndex(sesid, servdirtableid, "ClusterIDIndex")); CALL(JetMakeKey(sesid, servdirtableid, &ClusterID, sizeof(ClusterID), JET_bitNewKey)); CALL(JetSeek(sesid, servdirtableid, JET_bitSeekEQ | JET_bitSetIndexRange)); CALL(JetIndexRecordCount(sesid, servdirtableid, pNumberOfServers, TSSD_SERACH_MAX_RECORD)); TRC1((TB, "Number of Servers found is %d", *pNumberOfServers)); *ppServerInfo = (TSSD_ServerInfo *) MIDL_user_allocate(sizeof(TSSD_ServerInfo) * *pNumberOfServers); pServerInfo = *ppServerInfo; if (pServerInfo == NULL) { ERR((TB, "TSSDRpcQueryServersInCluster: Memory alloc failed!\n")); goto HandleError; } // Get all the servers for this ClusterID CALL(JetMove(sesid, servdirtableid, JET_MoveFirst, 0)); CALL(JetSetCurrentIndex(sesid, servdirtableid, "ClusterIDIndex")); CALL(JetMakeKey(sesid, servdirtableid, &ClusterID, sizeof(ClusterID), JET_bitNewKey)); CALL(JetSeek(sesid, servdirtableid, JET_bitSeekEQ | JET_bitSetIndexRange)); for (i=0; i<*pNumberOfServers; i++) { // retrive the info for ServerInfo CALL(JetRetrieveColumn(sesid, servdirtableid, servdircolumnid[ SERVDIR_SERVID_INTERNAL_INDEX], &ServerID, sizeof(ServerID), &cbActual, 0, NULL)); CALL(JetRetrieveColumn(sesid, servdirtableid, servdircolumnid[ SERVDIR_SERVDNSNAME_INTERNAL_INDEX], pServerInfo[i].ServerName, sizeof(pServerInfo[i].ServerName), &cbActual, 0, NULL)); CALL(JetRetrieveColumn(sesid, servdirtableid, servdircolumnid[ SERVDIR_SERVADDR_INTERNAL_INDEX], pServerInfo[i].ServerIPAddress, sizeof(pServerInfo[i].ServerIPAddress), &cbActual, 0, NULL)); CALL(JetRetrieveColumn(sesid, servdirtableid, servdircolumnid[ SERVDIR_SINGLESESS_INTERNAL_INDEX], &(pServerInfo[i].SingleSessionMode), sizeof(pServerInfo[i].SingleSessionMode), &cbActual, 0, NULL)); wcsncpy(pServerInfo[i].ClusterName, ClusterName, TSSD_NameLength); (pServerInfo[i].ClusterName)[TSSD_NameLength - 1] = L'\0'; // Find the session numbers for this server err = JetMove(sesid, sessdirtableid, JET_MoveFirst, 0); if (JET_errSuccess == err) { CALL(JetSetCurrentIndex(sesid, sessdirtableid, "ServerIndex")); CALL(JetMakeKey(sesid, sessdirtableid, (const void *)&ServerID, sizeof(ServerID), JET_bitNewKey)); err = JetSeek(sesid, sessdirtableid, JET_bitSeekEQ | JET_bitSetIndexRange); if (JET_errSuccess == err) { CALL(JetIndexRecordCount(sesid, sessdirtableid, &(pServerInfo[i].NumberOfSessions), TSSD_SERACH_MAX_RECORD)); } else { // This server doesn't have any sessions pServerInfo[i].NumberOfSessions = 0; } TRC1((TB,"TSSDRpcQueryServersInCluster: Get SessionNum is %d", pServerInfo[i].NumberOfSessions)); } else { // Session table is empty pServerInfo[i].NumberOfSessions = 0; } if (i != *pNumberOfServers - 1) { CALL(JetMove(sesid, servdirtableid, JET_MoveNext, 0)); } } CALL(JetCommitTransaction(sesid, 0)); CALL(JetCloseTable(sesid, servdirtableid)); CALL(JetCloseTable(sesid, clusdirtableid)); CALL(JetCloseDatabase(sesid, dbid, 0)); CALL(JetEndSession(sesid, 0)); rc = (DWORD)RPC_S_OK; HandleError: if ((sesid != JET_sesidNil) && (rc != 0)) { // Force the session closed (VOID) JetEndSession(sesid, JET_bitForceSessionClosed); } return rc; } // Query the info for all cluster DWORD TSSDRpcQueryAllClusterInfo( /* [in] */ handle_t Binding, /* [out] */ DWORD __RPC_FAR *pNumberOfClusters, /* [out] */ TSSD_ClusterInfo __RPC_FAR __RPC_FAR **ppClusterInfo) { Binding; pNumberOfClusters; TSSD_ClusterInfo *pClusterInfo; DWORD rc = (DWORD) E_FAIL; JET_SESID sesid = JET_sesidNil; JET_TABLEID clusdirtableid; JET_TABLEID servdirtableid; JET_DBID dbid; JET_ERR err; long *pClusterID = NULL; unsigned long cbActual; DWORD i; *pNumberOfClusters = 0; pClusterInfo = NULL; *ppClusterInfo = pClusterInfo; TRC1((TB,"TSSDRpcQueryAllClusterInfo")); CALL(JetBeginSession(g_instance, &sesid, "user", "")); CALL(JetOpenDatabase(sesid, JETDBFILENAME, "", &dbid, 0)); CALL(JetOpenTable(sesid, dbid, "ClusterDirectory", NULL, 0, 0, &clusdirtableid)); CALL(JetOpenTable(sesid, dbid, "ServerDirectory", NULL, 0, 0, &servdirtableid)); CALL(JetBeginTransaction(sesid)); // ClusterName is not specified // Get the ClusterID for all clusters err = JetMove(sesid, clusdirtableid, JET_MoveFirst, 0); if (err != JET_errSuccess) { TRC1((TB,"TSSDRpcQueryAllClusterInfo: Session Directory is empty")); goto HandleError; } CALL(JetIndexRecordCount(sesid, clusdirtableid, pNumberOfClusters, TSSD_SERACH_MAX_RECORD)); pClusterID = (long *)LocalAlloc(LMEM_FIXED, *pNumberOfClusters * sizeof(long)); if (pClusterID == NULL) { goto HandleError; } *ppClusterInfo = (TSSD_ClusterInfo *) MIDL_user_allocate(sizeof(TSSD_ClusterInfo) * *pNumberOfClusters); pClusterInfo = *ppClusterInfo; if (pClusterInfo == NULL) { TSDISErrorOut(L"TSSDRpcQueryClusterInfo: Memory alloc failed!\n"); goto HandleError; } err = JetMove(sesid, clusdirtableid, JET_MoveFirst, 0); i = 0; while (err != JET_errNoCurrentRecord) { CALL(JetRetrieveColumn(sesid, clusdirtableid, clusdircolumnid[ CLUSDIR_CLUSID_INTERNAL_INDEX], &pClusterID[i], sizeof(pClusterID[i]), &cbActual, 0, NULL)); CALL(JetRetrieveColumn(sesid, clusdirtableid, clusdircolumnid[ CLUSDIR_CLUSNAME_INTERNAL_INDEX], pClusterInfo[i].ClusterName, sizeof(pClusterInfo[i].ClusterName), &cbActual, 0, NULL)); CALL(JetRetrieveColumn(sesid, clusdirtableid, clusdircolumnid[ CLUSDIR_SINGLESESS_INTERNAL_INDEX], &(pClusterInfo[i].SingleSessionMode), sizeof(pClusterInfo[i].SingleSessionMode), &cbActual, 0, NULL)); err = JetMove(sesid, clusdirtableid, JET_MoveNext, 0); i++; } // Find the server numbers in this cluster for (i=0; i<*pNumberOfClusters; i++) { CALL(JetMove(sesid, servdirtableid, JET_MoveFirst, 0)); CALL(JetSetCurrentIndex(sesid, servdirtableid, "ClusterIDIndex")); CALL(JetMakeKey(sesid, servdirtableid, (const void *)&pClusterID[i], sizeof(pClusterID[i]), JET_bitNewKey)); CALL(JetSeek(sesid, servdirtableid, JET_bitSeekEQ | JET_bitSetIndexRange)); CALL(JetIndexRecordCount(sesid, servdirtableid, &(pClusterInfo[i].NumberOfServers), TSSD_SERACH_MAX_RECORD)); TRC1((TB,"TSSDRpcQueryClusterInfo: Get ServerNum is %d", pClusterInfo[0].NumberOfServers)); } CALL(JetCommitTransaction(sesid, 0)); CALL(JetCloseTable(sesid, servdirtableid)); CALL(JetCloseTable(sesid, clusdirtableid)); CALL(JetCloseDatabase(sesid, dbid, 0)); CALL(JetEndSession(sesid, 0)); rc = (DWORD)RPC_S_OK; HandleError: // Deallocate memory if (pClusterID != NULL) { LocalFree(pClusterID); } if ((sesid != JET_sesidNil) && (rc != 0)) { // Force the session closed (VOID) JetEndSession(sesid, JET_bitForceSessionClosed); } return rc; } // Query the cluster info by the cluster name DWORD TSSDRpcQueryClusterInfo( /* [in] */ handle_t Binding, /*[in] */ WCHAR __RPC_FAR *ClusterName, /* [out] */ DWORD __RPC_FAR *pNumberOfClusters, /* [out] */ TSSD_ClusterInfo __RPC_FAR __RPC_FAR **ppClusterInfo) { Binding; TSSD_ClusterInfo *pClusterInfo; DWORD rc = (DWORD) E_FAIL; JET_SESID sesid = JET_sesidNil; JET_TABLEID clusdirtableid; JET_TABLEID servdirtableid; JET_DBID dbid; JET_ERR err; long *pClusterID = NULL; unsigned long cbActual; DWORD i; *pNumberOfClusters = 0; pClusterInfo = NULL; TRC1((TB,"Query for cluster Name: %S", ClusterName)); CALL(JetBeginSession(g_instance, &sesid, "user", "")); CALL(JetOpenDatabase(sesid, JETDBFILENAME, "", &dbid, 0)); CALL(JetOpenTable(sesid, dbid, "ClusterDirectory", NULL, 0, 0, &clusdirtableid)); CALL(JetOpenTable(sesid, dbid, "ServerDirectory", NULL, 0, 0, &servdirtableid)); CALL(JetBeginTransaction(sesid)); // From the clustername find the clusterID CALL(JetSetCurrentIndex(sesid, clusdirtableid, "ClusNameIndex")); CALL(JetMakeKey(sesid, clusdirtableid, ClusterName, (unsigned) (wcslen(ClusterName) + 1) * sizeof(WCHAR), JET_bitNewKey)); err = JetSeek(sesid, clusdirtableid, JET_bitSeekEQ); if (err != JET_errSuccess) { TRC1((TB,"TSSDRpcQueryClusterInfo: Clustername %S does not exist", ClusterName)); goto HandleError; } *pNumberOfClusters = 1; pClusterID = (long *)LocalAlloc(LMEM_FIXED, *pNumberOfClusters * sizeof(long)); if (pClusterID == NULL) { TSDISErrorOut(L"TSSDRpcQueryClusterInfo: Memory alloc failed!\n"); goto HandleError; } *ppClusterInfo = (TSSD_ClusterInfo *) MIDL_user_allocate(sizeof(TSSD_ClusterInfo) * *pNumberOfClusters); pClusterInfo = *ppClusterInfo; if (pClusterInfo == NULL) { TSDISErrorOut(L"TSSDRpcQueryClusterInfo: Memory alloc failed!\n"); goto HandleError; } CALL(JetRetrieveColumn(sesid, clusdirtableid, clusdircolumnid[ CLUSDIR_CLUSID_INTERNAL_INDEX], &pClusterID[0], sizeof(pClusterID[0]), &cbActual, 0, NULL)); CALL(JetRetrieveColumn(sesid, clusdirtableid, clusdircolumnid[ CLUSDIR_CLUSNAME_INTERNAL_INDEX], pClusterInfo[0].ClusterName, sizeof(pClusterInfo[0].ClusterName), &cbActual, 0, NULL)); TRC1((TB,"TSSDRpcQueryClusterInfo: Get cluster name %S", pClusterInfo[0].ClusterName)); CALL(JetRetrieveColumn(sesid, clusdirtableid, clusdircolumnid[ CLUSDIR_SINGLESESS_INTERNAL_INDEX], &(pClusterInfo[0].SingleSessionMode), sizeof(pClusterInfo[0].SingleSessionMode), &cbActual, 0, NULL)); // Find the server numbers in this cluster for (i=0; i<*pNumberOfClusters; i++) { CALL(JetMove(sesid, servdirtableid, JET_MoveFirst, 0)); CALL(JetSetCurrentIndex(sesid, servdirtableid, "ClusterIDIndex")); CALL(JetMakeKey(sesid, servdirtableid, (const void *)&pClusterID[i], sizeof(pClusterID[i]), JET_bitNewKey)); CALL(JetSeek(sesid, servdirtableid, JET_bitSeekEQ | JET_bitSetIndexRange)); CALL(JetIndexRecordCount(sesid, servdirtableid, &(pClusterInfo[i].NumberOfServers), TSSD_SERACH_MAX_RECORD)); TRC1((TB,"TSSDRpcQueryClusterInfo: Get ServerNum is %d", pClusterInfo[i].NumberOfServers)); } CALL(JetCommitTransaction(sesid, 0)); CALL(JetCloseTable(sesid, servdirtableid)); CALL(JetCloseTable(sesid, clusdirtableid)); CALL(JetCloseDatabase(sesid, dbid, 0)); CALL(JetEndSession(sesid, 0)); rc = (DWORD)RPC_S_OK; HandleError: // Deallocate memory if (pClusterID != NULL) { LocalFree(pClusterID); } if ((sesid != JET_sesidNil) && (rc != 0)) { // Force the session closed (VOID) JetEndSession(sesid, JET_bitForceSessionClosed); } return rc; } #pragma warning (pop)