home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / dbmsg / mapi / remote.srv / admnotif.cpp < prev    next >
C/C++ Source or Header  |  1996-04-11  |  17KB  |  489 lines

  1. ///////////////////////////////////////////////////////////////////////////////
  2. //
  3. //  File Name 
  4. //      ADMNOTIF.CPP
  5. //
  6. //  Description
  7. //
  8. //  Author
  9. //      Irving De la Cruz
  10. //
  11. //  Revision: 1.7
  12. //
  13. // Written for Microsoft Windows Developer Support
  14. // Copyright (c) 1995-1996 Microsoft Corporation. All rights reserved.
  15. //
  16. #include "ADMIN.H"
  17.  
  18. // Remark this line to turn verbose tracing OFF
  19. //#define DO_INFO_TRACES
  20. #ifdef DO_INFO_TRACES
  21. #define InfoTrace(a)        TraceInfoMessage(a)
  22. #else
  23. #define InfoTrace(a)        0
  24. #endif // DO_INFO_TRACES
  25.  
  26. ///////////////////////////////////////////////////////////////////////////////
  27. //    BindToServer()
  28. //
  29. //    Parameters
  30. //      [IN]    szServer   Name of the remote server to which we will bind
  31. //                         for RPC calls. If this pointer is NULL, we
  32. //                         unbind from that server.
  33. //
  34. //    Purpose
  35. //      This function makes the necessary calls to the RPC runtime library
  36. //      to bind to the remote server so that we can start RPC function calls.
  37. //
  38. //    Return Value
  39. //      An HRESULT
  40. //
  41. HRESULT WINAPI BindToServer (LPTSTR szServer)
  42. {
  43.     static TCHAR szLastServer[64] = { 0 };
  44.     static TCHAR * szStringBinding = NULL;
  45.     
  46.     // If a server name was given, we compare to the current server that we are
  47.     // already bounded to. If we are connected return the call.
  48.     if (szServer)
  49.     {
  50.         if (0 == lstrcmpi (szLastServer, szServer))
  51.         {
  52.             if (szStringBinding)
  53.             {
  54.                 return 0;
  55.             }
  56.         }
  57.         else
  58.         {
  59.             // Save the name of the server in the static buffer
  60.             lstrcpy (szLastServer, szServer);
  61.         }
  62.     }
  63.  
  64.     RPC_STATUS status = 0;
  65.     if (szStringBinding) // Unbind only if bound
  66.     {
  67.         status = RpcStringFree ((WINDS_RPC_STRING*)&szStringBinding);
  68.         if (!status)
  69.         {
  70.             szStringBinding = NULL;
  71.             status = RpcBindingFree (&hWINDSADM);  // hWINDSADM is defined in WDSADM.H and WDSADM.ACF
  72.         }
  73.         if (status)
  74.         {
  75.             status = MAKE_HRESULT(1, FACILITY_RPC, status);
  76.             TraceResult ("BindToServer: Failed to free the binding", status);
  77.         }
  78.     }
  79.     // If this is NULL, then we don't need to bind to anything.
  80.     if (!szServer)
  81.     {
  82.         szLastServer[0] = 0;
  83.         return S_OK;
  84.     }
  85.     if (!status)
  86.     {
  87.         status = RpcStringBindingCompose (NULL,
  88.                                           (WINDS_RPC_STRING)WINDS_RPC_PROTOCOL,
  89.                                           (WINDS_RPC_STRING)szServer,
  90.                                           (WINDS_RPC_STRING)WINDS_ADMIN_RPC_ENDPOINT,
  91.                                           NULL,
  92.                                           (WINDS_RPC_STRING*)&szStringBinding);
  93.         if (!status)
  94.         {
  95.             status = RpcBindingFromStringBinding ((WINDS_RPC_STRING)szStringBinding, &hWINDSADM); // hWINDSADM is defined in WDSADM.H and WDSADM.ACF
  96.         }
  97.     }
  98.     if (status)
  99.     {
  100.         szLastServer[0] = 0;
  101.         status = MAKE_HRESULT(1, FACILITY_RPC, status);
  102.         TraceResult ("BindToServer: Failed to create remote server binding handle", status);
  103.     }
  104.     return status;
  105. }
  106.  
  107. ///////////////////////////////////////////////////////////////////////////////
  108. //    CNotifLink::CNotifLink()
  109. //
  110. //    Parameters
  111. //
  112. //    Purpose
  113. //
  114. //    Return Value
  115. //
  116. CNotifLink::CNotifLink()
  117. {
  118.     m_hMailSlot = NULL;
  119.     m_ulConnectionID = 0;
  120.     ZeroMemory (m_szComputerName, sizeof(m_szComputerName));
  121.     DWORD dwNameSize = MAX_COMPUTERNAME_LENGTH + 1;
  122.     GetComputerName (m_szComputerName, &dwNameSize);
  123. }
  124.  
  125. ///////////////////////////////////////////////////////////////////////////////
  126. //    CNotifLink::~CNotifLink()
  127. //
  128. //    Parameters
  129. //
  130. //    Purpose
  131. //
  132. //    Return Value
  133. //
  134. CNotifLink::~CNotifLink()
  135. {
  136.     EndNotifications();
  137. }
  138.  
  139. ///////////////////////////////////////////////////////////////////////////////
  140. //    CNotifLink::EndNotifications()
  141. //
  142. //    Parameters
  143. //
  144. //    Purpose
  145. //
  146. //    Return Value
  147. //
  148. STDMETHODIMP CNotifLink::EndNotifications()
  149. {
  150.     if (0 == m_ulConnectionID)
  151.     {
  152.         ASSERT (NULL == m_hMailSlot);
  153.         return S_OK;
  154.     }
  155.     CloseHandle (m_hMailSlot);
  156.     m_hMailSlot = NULL;
  157.     HRESULT hResult;
  158.     RpcTryExcept
  159.     {
  160.         hResult = RemoteAdmTerminateNotif ((WINDS_RPC_STRING)m_szComputerName, m_ulConnectionID);
  161.     }
  162.     RpcExcept(1)
  163.     {
  164.         hResult = RpcExceptionCode();
  165.         if (RPC_S_SERVER_UNAVAILABLE == hResult)
  166.         {
  167.             hResult = HRESULT_FROM_WIN32(ERROR_HOST_UNREACHABLE);
  168.         }
  169.         else
  170.         {
  171.             hResult = MAKE_HRESULT(1, FACILITY_RPC, hResult);
  172.         }
  173.     }
  174.     RpcEndExcept
  175.     m_ulConnectionID = 0;
  176.     return hResult;
  177. }
  178.  
  179. ///////////////////////////////////////////////////////////////////////////////
  180. //    CNotifLink::StartNotification()
  181. //
  182. //    Parameters
  183. //
  184. //    Purpose
  185. //
  186. //    Return Value
  187. //
  188. STDMETHODIMP CNotifLink::StartNotification()
  189. {
  190.     if (0 != m_ulConnectionID)
  191.     {
  192.         return S_OK;
  193.     }
  194.     DWORD dwThreadID, dwFlags = WINDS_ADMINISTRATOR |
  195.                                 WINDS_NOTIF_ON_USER |
  196.                                 WINDS_NOTIF_ON_AB |
  197.                                 WINDS_NOTIF_ON_MS;
  198. #ifdef UNICODE
  199.     dwFlags |= WINDS_UNICODE;
  200. #endif // UNICODE
  201.  
  202.     HANDLE hThread;
  203.     TCHAR szMailslotName[64];
  204.     HRESULT hResult = S_OK;
  205.     RpcTryExcept
  206.     {
  207.         hResult = RemoteAdmValidateNotif ((WINDS_RPC_STRING)m_szComputerName,
  208.                                           dwFlags,
  209.                                           &m_ulConnectionID);
  210.     }
  211.     RpcExcept(1)
  212.     {
  213.         hResult = RpcExceptionCode();
  214.         if (RPC_S_SERVER_UNAVAILABLE == hResult)
  215.         {
  216.             hResult = HRESULT_FROM_WIN32(ERROR_HOST_UNREACHABLE);
  217.         }
  218.         else
  219.         {
  220.             hResult = MAKE_HRESULT(1, FACILITY_RPC, hResult);
  221.         }
  222.     }
  223.     RpcEndExcept
  224.     if (!hResult)
  225.     {
  226.         wsprintf (szMailslotName,
  227.                   CLIENT_MAILSLOT_SINK_NAME_FORMAT,
  228.                   ADMIN_WINDS_NOTIFICATION_MAILSLOT,
  229.                   m_ulConnectionID);
  230.         m_hMailSlot = CreateMailslot (szMailslotName, 0, MAILSLOT_WAIT_FOREVER, NULL);
  231.         if (INVALID_HANDLE_VALUE == m_hMailSlot)
  232.         {
  233.             hResult = HRESULT_FROM_WIN32(GetLastError());
  234.         }
  235.         else
  236.         {
  237.             hThread = CreateThread (NULL,
  238.                                     0,
  239.                                     (LPTHREAD_START_ROUTINE)MailslotListenThreadProc,
  240.                                     (LPVOID)this,
  241.                                     CREATE_SUSPENDED,
  242.                                     &dwThreadID);
  243.             if (hThread)
  244.             {
  245.                 SetThreadPriority (hThread, THREAD_PRIORITY_LOWEST);
  246.                 ResumeThread (hThread);
  247.                 CloseHandle (hThread);
  248.             }
  249.             else
  250.             {
  251.                 hResult = HRESULT_FROM_WIN32(GetLastError());
  252.                 CloseHandle (m_hMailSlot);
  253.             }
  254.         }
  255.         if (hResult)
  256.         {
  257.             EndNotifications();
  258.         }
  259.     }
  260.     TraceResult ("CNotifLink::StartNotification", hResult);
  261.     return hResult;
  262. }
  263.  
  264. ///////////////////////////////////////////////////////////////////////////////
  265. //    MailslotListenThreadProc()
  266. //
  267. //    Parameters
  268. //
  269. //    Purpose
  270. //      This is function runs in a separate low priority thread listening for
  271. //      notification that a WINDS server sends.. When a
  272. //      notification of interest is received, an appropiate action is taken.
  273. //      The notification arrive on a mailslot created by the logon object.
  274. //
  275. //    Return Value
  276. //      S_OK always.
  277. //
  278. DWORD WINAPI MailslotListenThreadProc (CNotifLink * pLink)
  279. {
  280.     TCHAR szBuffer[256] = { 0 };
  281.     LV_FINDINFO lfi = { 0 };
  282.     LV_ITEM lvi = { 0 };
  283.     
  284.     HANDLE hMailslot = pLink->GetListenMailslot();
  285.     DWORD dwRead;
  286.     FILETIME ftLastNotifTime = { 0 };
  287.     WINDS_NOTIF_EVENT LastEvent;
  288.     WINDS_NOTIFICATION Notif;
  289.     HRESULT hReadError;
  290.     while (TRUE)
  291.     {
  292.         if (!ReadFile (hMailslot, &Notif, sizeof(WINDS_NOTIFICATION), &dwRead, NULL)) 
  293.         { 
  294.             hReadError = HRESULT_FROM_WIN32 (GetLastError());
  295.             if (HRESULT_FROM_WIN32(ERROR_INVALID_HANDLE) == hReadError ||
  296.                 HRESULT_FROM_WIN32(ERROR_HANDLE_EOF) == hReadError)
  297.             {
  298.                 break; // out of the WHILE() loop and terminate the thread
  299.             }
  300.             TraceResult ("MailslotListenThreadProc: ReadFile", HRESULT_FROM_WIN32(GetLastError()));
  301.             continue;
  302.         }
  303.         // Mailslot are received in each network protocol stack installed on the system.
  304.         // Check the time stamp and event of the last notification received. If it
  305.         // is the same, drop it and continue listen for new and different incoming
  306.         // data on the mailslot.
  307.         if (ftLastNotifTime.dwLowDateTime  == Notif.ftEventTime.dwLowDateTime &&
  308.             ftLastNotifTime.dwHighDateTime == Notif.ftEventTime.dwHighDateTime &&
  309.             LastEvent                      == Notif.Event)
  310.         {
  311.             continue;
  312.         }
  313.         // Save the last event information
  314.         ftLastNotifTime = Notif.ftEventTime;
  315.         LastEvent = Notif.Event;
  316.  
  317.         #ifdef DO_INFO_TRACES
  318.         switch (Notif.Event)
  319.         {
  320.             case AB_USER_ADDED :
  321.                 InfoTrace ("AB_USER_ADDED notification received from the WINDS server");
  322.                 break;
  323.             case AB_USER_MODIFIED :
  324.                 InfoTrace ("AB_USER_MODIFIED notification received from the WINDS server");
  325.                 break;
  326.             case AB_USER_DELETED :
  327.                 InfoTrace ("AB_USER_DELETED notification received from the WINDS server");
  328.                 break;
  329.             case AB_DL_ADDED :
  330.                 InfoTrace ("AB_DL_ADDED notification received from the WINDS server");
  331.                 break;
  332.             case AB_DL_MODIFIED :
  333.                 InfoTrace ("AB_DL_MODIFIED notification received from the WINDS server");
  334.                 break;
  335.             case AB_DL_DELETED :
  336.                 InfoTrace ("AB_DL_DELETED notification received from the WINDS server");
  337.                 break;
  338.             case MS_MESSAGE_ADDED :
  339.             case MS_MESSAGE_MODIFIED :
  340.             case MS_MESSAGE_DELETED :
  341.             case MS_FOLDER_ADDED :
  342.             case MS_FOLDER_MODIFIED :
  343.             case MS_FOLDER_DELETED :
  344.                 break;
  345.             case SERVER_IS_SHUTTING_DOWN :
  346.                 InfoTrace ("SERVER_IS_SHUTTING_DOWN notification received from the WINDS server");
  347.                 break;
  348.             case RESET_LINKS_WITH_SERVER :
  349.                 InfoTrace ("RESET_LINKS_WITH_SERVER notification received from the WINDS server");
  350.                 break;
  351.             case SERVER_HAS_RESTARTED :
  352.                 InfoTrace ("SERVER_HAS_RESTARTED notification received from the WINDS server");
  353.                 break;
  354.             case AB_GET_LOCAL_ABDATA_NOW :
  355.                 InfoTrace ("AB_GET_LOCAL_ABDATA_NOW notification received from the WINDS server");
  356.                 break;
  357.             default :
  358.                 InfoTrace ("UNKNOWN notification received from the WINDS server");
  359.                 break;
  360.         }
  361.         #endif // DO_INFO_TRACES
  362.  
  363.         switch (Notif.Event)
  364.         {
  365.             case AB_USER_ADDED :
  366.             case AB_DL_ADDED :
  367.                 {
  368.                     if (AB_USER_ADDED == Notif.Event)
  369.                     {
  370.                         if (ITEM_SERVER_USER_MAILBOXES != g_LVItemsType)
  371.                         {
  372.                             break;
  373.                         }
  374.                     }
  375.                     else
  376.                     {
  377.                         if (ITEM_SERVER_DIST_LISTS != g_LVItemsType)
  378.                         {
  379.                             break;
  380.                         }
  381.                     }
  382.  
  383.                     int iNewItem = ListView_GetItemCount (ghListView);
  384.                     lvi.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM;
  385.                     lvi.iItem = iNewItem;
  386.                     lvi.iSubItem = 0;
  387.                     if (AB_USER_ADDED == Notif.Event)
  388.                     {
  389.                         
  390.                         lvi.pszText = Notif.Info.MB.szMailboxName;
  391.                         lvi.lParam = Notif.Info.MB.dwObjID;
  392.                         lvi.iImage = IMG_USER_MAILBOX;
  393.                     }
  394.                     else
  395.                     {
  396.                         lvi.pszText = Notif.Info.DL.szDLAlias;
  397.                         lvi.lParam = Notif.Info.DL.dwObjID;
  398.                         lvi.iImage = IMG_DIST_LIST;
  399.                     }
  400.                     lvi.iItem = ListView_InsertItem (ghListView, &lvi);
  401.                     if (AB_USER_ADDED == Notif.Event)
  402.                     {
  403.                         ListView_SetItemText (ghListView, lvi.iItem, 1, Notif.Info.MB.szFullName);
  404.                         ListView_SetItemText (ghListView, lvi.iItem, 2, Notif.Info.MB.szJobTitle);
  405.                         ListView_SetItemText (ghListView, lvi.iItem, 3, Notif.Info.MB.szOffice);
  406.                         ListView_SetItemText (ghListView, lvi.iItem, 4, Notif.Info.MB.szPhone);
  407.                         ListView_SetItemText (ghListView, lvi.iItem, 5, Notif.Info.MB.szAltPhone);
  408.                         ListView_SetItemText (ghListView, lvi.iItem, 6, Notif.Info.MB.szFax);
  409.                     }
  410.                     else
  411.                     {
  412.                         ListView_SetItemText (ghListView, lvi.iItem, 1, Notif.Info.DL.szDLFullName);
  413.                     }
  414.                 }
  415.                 break;
  416.  
  417.             case AB_USER_DELETED :
  418.             case AB_USER_MODIFIED :
  419.             case AB_DL_DELETED :
  420.             case AB_DL_MODIFIED :
  421.                 if (AB_USER_DELETED == Notif.Event || AB_USER_MODIFIED == Notif.Event)
  422.                 {
  423.                     if (ITEM_SERVER_USER_MAILBOXES != g_LVItemsType)
  424.                     {
  425.                         break;
  426.                     }
  427.                 }
  428.                 else
  429.                 {
  430.                     if (ITEM_SERVER_DIST_LISTS != g_LVItemsType)
  431.                     {
  432.                         break;
  433.                     }
  434.                 }
  435.                 lfi.flags = LVFI_STRING;
  436.                 if (AB_USER_MODIFIED == Notif.Event || AB_USER_DELETED == Notif.Event)
  437.                 {
  438.                     lfi.psz = Notif.Info.MB.szMailboxName;
  439.                 }
  440.                 else
  441.                 {
  442.                     lfi.psz = Notif.Info.DL.szDLAlias;
  443.                 }
  444.                 lvi.iItem = ListView_FindItem (ghListView, -1, &lfi);
  445.                 if (-1 == lvi.iItem)
  446.                 {
  447.                     break;
  448.                 }
  449.                 if (AB_DL_DELETED == Notif.Event || AB_USER_DELETED == Notif.Event)
  450.                 {
  451.                     ListView_DeleteItem (ghListView, lvi.iItem);
  452.                 }
  453.                 else
  454.                 {
  455.                     lvi.mask = LVIF_TEXT | LVIF_PARAM | LVIF_IMAGE;
  456.                     lvi.iSubItem = 0;
  457.                     if (AB_USER_MODIFIED == Notif.Event)
  458.                     {
  459.                         lvi.pszText = Notif.Info.MB.szMailboxName;
  460.                         lvi.lParam = Notif.Info.MB.dwObjID;
  461.                         lvi.iImage = IMG_USER_MAILBOX;
  462.                         ListView_SetItem (ghListView, &lvi);
  463.                         ListView_SetItemText (ghListView, lvi.iItem, 1, Notif.Info.MB.szFullName);
  464.                         ListView_SetItemText (ghListView, lvi.iItem, 2, Notif.Info.MB.szJobTitle);
  465.                         ListView_SetItemText (ghListView, lvi.iItem, 3, Notif.Info.MB.szOffice);
  466.                         ListView_SetItemText (ghListView, lvi.iItem, 4, Notif.Info.MB.szPhone);
  467.                         ListView_SetItemText (ghListView, lvi.iItem, 5, Notif.Info.MB.szAltPhone);
  468.                         ListView_SetItemText (ghListView, lvi.iItem, 6, Notif.Info.MB.szFax);
  469.                     }
  470.                     else
  471.                     {
  472.                         lvi.pszText = Notif.Info.DL.szDLAlias;
  473.                         lvi.lParam = Notif.Info.DL.dwObjID;
  474.                         lvi.iImage = IMG_DIST_LIST;
  475.                         ListView_SetItem (ghListView, &lvi);
  476.                         ListView_SetItemText (ghListView, lvi.iItem, 1, Notif.Info.DL.szDLFullName);
  477.                     }
  478.                 }
  479.                 break;
  480.             case RESET_LINKS_WITH_SERVER :
  481.                 PostMessage (ghWnd, WM_WINDS_RESET_NOTIF_LINK, 0, 0);
  482.                 break;
  483.         }
  484.     } 
  485.     return S_OK;
  486. }
  487.  
  488. // End of file for ADMNOTIF.CPP
  489.