home *** CD-ROM | disk | FTP | other *** search
- #include <windows.h>
- #include <stdio.h>
- #include <string.h>
- #include "Remote.h"
- #include "Server.h"
-
- //
- // This module uses mailslots to broadcast the existence of
- // this remote server to allow a form of browsing for
- // remote server instances. This is disabled in the
- // customer version of remote.exe, and can be disabled
- // in the internal version using the /v- switch to
- // remote /s.
- //
- // remoteds.c implements a listener that allows searching.
- //
-
- #define INITIAL_SLEEP_PERIOD (35 * 1000) // 35 seconds before first
- #define INITIAL_AD_RATE (10 * 60 * 1000) // 10 minutes between 1 & 2,
- #define MAXIMUM_AD_RATE (120 * 60 * 1000) // doubling until 120 minutes max
-
-
- OVERLAPPED olMailslot;
- HANDLE hAdTimer = INVALID_HANDLE_VALUE;
- HANDLE hMailslot = INVALID_HANDLE_VALUE;
- DWORD dwTimerInterval; // milliseconds
- BOOL bSynchAdOnly;
- BOOL bSendingToMailslot;
- char szMailslotName[64]; // netbios names are short
- char szSend[1024];
-
-
- #define MAX_MAILSLOT_SPEWS 2
- DWORD dwMailslotErrors;
-
-
- VOID
- InitAd(
- BOOL IsAdvertise
- )
- {
- DWORD cb;
- PWKSTA_INFO_101 pwki101;
- LARGE_INTEGER DueTime;
-
- if (IsAdvertise) {
-
- // Unless Win32s or Win9x support named pipe servers...
-
- ASSERT(OsVersionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT);
-
- // Problems with overlapped writes to a mailslot sometimes
- // cause remote.exe to zombie on exit on NT4, undebuggable
- // and unkillable because of an abandoned RDR1 IRP which
- // never completes.
- //
- // So on NT4 we only send messages at startup and shutdown
- // and send them synchronously using a nonoverlapped handle.
- //
-
- bSynchAdOnly = (OsVersionInfo.dwMajorVersion <= 4);
-
- //
- // Get currently active computername and browser/mailslot
- // domain/workgroup using one call to NetWkstaGetInfo.
- // This is unicode-only, we'll use wsprintf's %ls to
- // convert to 8-bit characters.
- //
- // remoteds.exe needs to be run on a workstation that is
- // part of the domain or workgroup of the same name,
- // and be in broadcast range, to receive our sends.
- //
-
- if (pfnNetWkstaGetInfo(NULL, 101, (LPBYTE *) &pwki101)) {
- printf("REMOTE: unable to get computer/domain name, not advertising.\n");
- return;
- }
-
- wsprintf(
- szMailslotName,
- "\\\\%ls\\MAILSLOT\\REMOTE\\DEBUGGERS",
- pwki101->wki101_langroup
- );
-
- wsprintf(
- szSend,
- "%ls\t%d\t%s\t%s",
- pwki101->wki101_computername,
- GetCurrentProcessId(),
- PipeName,
- ChildCmd
- );
-
- pfnNetApiBufferFree(pwki101);
- pwki101 = NULL;
-
- //
- // Broadcast mailslots are limited to 400 message bytes
- //
-
- szSend[399] = 0;
-
- if (bSynchAdOnly) {
-
- hMailslot =
- CreateFile(
- szMailslotName,
- GENERIC_WRITE,
- FILE_SHARE_WRITE,
- NULL,
- OPEN_EXISTING,
- 0,
- NULL
- );
-
- if ( ! WriteFile(
- hMailslot,
- szSend,
- strlen(szSend) + 1,
- &cb,
- NULL
- )) {
-
- printf("REMOTE: WriteFile Failed on mailslot, error %d\n", GetLastError());
- }
-
- } else { // we can do async mailslot I/O
-
- //
- // Create a waitable timer and set it to fire first in
- // INITIAL_SLEEP_PERIOD milliseconds by calling the
- // completion routine AdvertiseTimerFired. It will
- // be given an inital period of INITIAL_AD_RATE ms.
- //
-
- hAdTimer =
- pfnCreateWaitableTimer(
- NULL, // security
- FALSE, // bManualReset, we want auto-reset
- NULL // unnamed
- );
-
- DueTime.QuadPart = Int32x32To64(INITIAL_SLEEP_PERIOD, -10000);
- dwTimerInterval = INITIAL_AD_RATE;
-
- pfnSetWaitableTimer(
- hAdTimer,
- &DueTime,
- dwTimerInterval,
- AdvertiseTimerFired,
- 0, // arg to compl. rtn
- TRUE
- );
-
- }
- }
- }
-
-
- VOID
- ShutAd(
- BOOL IsAdvertise
- )
- {
- DWORD cb;
- BOOL b;
-
- if (IsAdvertise) {
-
- if (INVALID_HANDLE_VALUE != hAdTimer) {
-
- pfnCancelWaitableTimer(hAdTimer);
- CloseHandle(hAdTimer);
- hAdTimer = INVALID_HANDLE_VALUE;
- }
-
- if (INVALID_HANDLE_VALUE != hMailslot &&
- ! bSendingToMailslot) {
-
- //
- // Tell any listening remoteds's we're
- // outta here. Do this by tacking on
- // a ^B at the end of the string (as
- // in Bye).
- //
-
- strcat(szSend, "\x2");
-
-
- if (bSynchAdOnly) { // overlapped handle or not?
- b = WriteFile(
- hMailslot,
- szSend,
- strlen(szSend) + 1,
- &cb,
- NULL
- );
- } else {
- b = WriteFileSynch(
- hMailslot,
- szSend,
- strlen(szSend) + 1,
- &cb,
- 0,
- &olMainThread
- );
- }
-
- if ( ! b ) {
-
- printf("REMOTE: WriteFile Failed on mailslot, error %d\n", GetLastError());
- }
-
- }
-
- if (INVALID_HANDLE_VALUE != hMailslot) {
-
- printf("\rREMOTE: closing mailslot... ");
- fflush(stdout);
- CloseHandle(hMailslot);
- hMailslot = INVALID_HANDLE_VALUE;
- printf("\r \r");
- fflush(stdout);
- }
- }
- }
-
-
- VOID
- APIENTRY
- AdvertiseTimerFired(
- LPVOID pArg,
- DWORD dwTimerLo,
- DWORD dwTimerHi
- )
- {
- UNREFERENCED_PARAMETER( pArg );
- UNREFERENCED_PARAMETER( dwTimerLo );
- UNREFERENCED_PARAMETER( dwTimerHi );
-
-
- if (INVALID_HANDLE_VALUE == hMailslot) {
-
- hMailslot =
- CreateFile(
- szMailslotName,
- GENERIC_WRITE,
- FILE_SHARE_WRITE,
- NULL,
- OPEN_EXISTING,
- FILE_FLAG_OVERLAPPED,
- NULL
- );
- }
-
- if (INVALID_HANDLE_VALUE != hMailslot) {
-
- ZeroMemory(&olMailslot, sizeof(olMailslot));
-
- bSendingToMailslot = TRUE;
-
- if ( ! WriteFileEx(
- hMailslot,
- szSend,
- strlen(szSend) + 1,
- &olMailslot,
- WriteMailslotCompleted
- )) {
-
- bSendingToMailslot = FALSE;
-
- if (++dwMailslotErrors <= MAX_MAILSLOT_SPEWS) {
-
- DWORD dwError;
- char szErrorText[512];
-
- dwError = GetLastError();
-
- FormatMessage(
- FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
- NULL,
- dwError,
- 0,
- szErrorText,
- sizeof szErrorText,
- NULL
- );
-
- //
- // FormatMessage has put a newline at the end of szErrorText
- //
-
- printf(
- "REMOTE: Advertisement failed, mailslot error %d:\n%s",
- dwError,
- szErrorText
- );
- }
-
- //
- // Try reopening the mailslot next time, can't hurt.
- //
-
- CloseHandle(hMailslot);
- hMailslot = INVALID_HANDLE_VALUE;
- }
- }
- }
-
-
- VOID
- WINAPI
- WriteMailslotCompleted(
- DWORD dwError,
- DWORD cbWritten,
- LPOVERLAPPED lpO
- )
- {
- LARGE_INTEGER DueTime;
-
- bSendingToMailslot = FALSE;
-
- if (dwError ||
- (strlen(szSend) + 1) != cbWritten) {
-
- if (++dwMailslotErrors <= MAX_MAILSLOT_SPEWS) {
- printf("REMOTE: write failed on mailslot, error %d cb %d (s/b %d)\n",
- dwError, cbWritten, (strlen(szSend) + 1));
- }
- return;
- }
-
- //
- // If we succeeded in writing the mailslot, double the timer interval
- // up to the limit.
- //
-
- if (dwTimerInterval < MAXIMUM_AD_RATE) {
-
- dwTimerInterval = max(dwTimerInterval * 2, MAXIMUM_AD_RATE);
-
- DueTime.QuadPart = Int32x32To64(dwTimerInterval, -10000);
-
- if (INVALID_HANDLE_VALUE != hAdTimer) {
-
- pfnSetWaitableTimer(
- hAdTimer,
- &DueTime,
- dwTimerInterval,
- AdvertiseTimerFired,
- 0, // arg to compl. rtn
- TRUE
- );
- }
- }
- }
-