def Main(pipeName, debugLevel):
    if debugLevel:

        def Debug(msg):
            sys.stdout.write(msg + "\n")
    else:

        def Debug(msg):
            pass

    if not WaitNamedPipe(pipeName, 5000):
        raise WinError()
    hPipe = CreateFile(pipeName, GENERIC_READ | GENERIC_WRITE,
                       FILE_SHARE_READ | FILE_SHARE_WRITE, None, OPEN_EXISTING,
                       0, None)
    if hPipe == INVALID_HANDLE_VALUE:
        raise WinError()
    try:
        # The pipe connected; change to message-read mode.
        dwMode = DWORD(PIPE_READMODE_MESSAGE)
        if not SetNamedPipeHandleState(hPipe, byref(dwMode), None, None):
            raise WinError()

        sys.stderr = PipeStream(hPipe, MESSAGE_STDERR)
        sys.stdout = PipeStream(hPipe, MESSAGE_STDOUT)
        Debug("reading startup message")
        code, (scriptPath, funcName, args, kwargs) = ReadPipeMessage(hPipe)
        Debug("got startup message:\n"
              "  path: %r\n"
              "  funcName: %r\n"
              "  args: %r\n"
              "  kwargs: %r" % (scriptPath, funcName, args, kwargs))
        if code != MESSAGE_ARGS:
            raise Exception("Unexpected message type")
        try:
            moduleName = splitext(basename(scriptPath))[0]
            try:
                moduleInfo = imp.find_module(moduleName, [dirname(scriptPath)])
            except ImportError:
                import zipimport
                for entry in sys.path:
                    if entry.endswith('.zip'):
                        zipImporter = zipimport.zipimporter(entry)
                        try:
                            module = zipImporter.load_module(moduleName)
                        except zipimport.ZipImportError:
                            continue
            else:
                module = imp.load_module(moduleName, *moduleInfo)
            func = getattr(module, funcName)
            result = func(*args, **kwargs)
            Debug("result: %r" % result)
        except:
            WritePipeMessage(hPipe, MESSAGE_EXCEPTION,
                             FormatException(sys.exc_info()))
        else:
            WritePipeMessage(hPipe, MESSAGE_RESULT, result)
    finally:
        CloseHandle(hPipe)
Beispiel #2
0
def PyGetWindowThreadProcessId(hWnd):
    """
    Retrieves the identifier of the thread and process that created the
    specified window.

    int threadId, int processId = GetWindowThreadProcessId(hWnd)
    """
    dwProcessId = DWORD()
    threadId = GetWindowThreadProcessId(hWnd, byref(dwProcessId))
    return threadId, dwProcessId.value
Beispiel #3
0
 def GetStatus(self):
     dwBytesNeeded = DWORD()
     result = QueryServiceStatusEx(
         self.schService,  # handle to service
         SC_STATUS_PROCESS_INFO,  # information level
         cast(byref(self.ssStatus), LPBYTE),  # address of structure
         sizeof(self.ssStatus),  # size of structure
         byref(dwBytesNeeded)  # size needed if buffer is too small
     )
     if not result:
         raise WinError()
     return self.ssStatus
Beispiel #4
0
def PySendMessageTimeout(hWnd,
                         msg,
                         wParam=0,
                         lParam=0,
                         flags=SMTO_BLOCK | SMTO_ABORTIFHUNG,
                         timeout=2000):
    resultData = DWORD()
    res = SendMessageTimeout(hWnd, msg, wParam, lParam, flags, timeout,
                             byref(resultData))
    if not res:
        raise WinError()
    return resultData.value
Beispiel #5
0
def WritePipeMessage(hPipe, code, data):
    message = dumps((code, data))
    cbWritten = DWORD(0)
    fSuccess = WriteFile(
        hPipe,
        message,
        len(message),
        byref(cbWritten),
        None
    )
    if (not fSuccess) or (len(message) != cbWritten.value):
        raise Exception("WritePipeMessage failed")
Beispiel #6
0
def GetUncPathOf(filePath):
    buf = create_string_buffer(1024)
    dwBufSize = DWORD(1024)
    err = WNetGetUniversalName(filePath, UNIVERSAL_NAME_INFO_LEVEL, buf,
                               byref(dwBufSize))
    if err == 0:
        return cast(buf, POINTER(UNIVERSAL_NAME_INFO)).contents.lpUniversalName
    elif err == ERROR_NOT_CONNECTED:
        pass
    else:
        print "GetUncPathOf Error:", err, FormatError(err)
    return filePath
Beispiel #7
0
def GetHwndIcon(hWnd):
    """
    Get a wx.Icon from a window through its hwnd window handle
    """
    hIcon = DWORD()
    res = SendMessageTimeout(hWnd, WM_GETICON, ICON_SMALL, 0, SMTO_ABORTIFHUNG,
                             1000, byref(hIcon))

    if res == 0:
        hIcon.value = 0
    if hIcon.value < 10:
        hIcon.value = GetClassLong(hWnd, GCL_HICONSM)
        if hIcon.value == 0:
            res = SendMessageTimeout(hWnd, WM_GETICON, ICON_BIG, 0,
                                     SMTO_ABORTIFHUNG, 1000, byref(hIcon))
            if res == 0:
                hIcon.value = 0
            if hIcon.value < 10:
                hIcon.value = GetClassLong(hWnd, GCL_HICON)
    if hIcon.value != 0:
        icon = wx.NullIcon
        value = hIcon.value
        # ugly fix for "OverflowError: long int too large to convert to int"
        if value & 0x80000000:
            value = -((value ^ 0xffffffff) + 1)
        icon.SetHandle(value)
        icon.SetSize((16, 16))
        return icon
    else:
        return None
Beispiel #8
0
def PyEnumProcesses():
    size = 1024
    pBytesReturned = DWORD()
    while True:
        data = (DWORD * size)()
        dataSize = size * sizeof(DWORD)
        res = EnumProcesses(data, dataSize, byref(pBytesReturned))
        if res == 0:
            raise WinError()
        if pBytesReturned.value != dataSize:
            break
        size *= 10
    return data[:pBytesReturned.value / sizeof(DWORD)]
Beispiel #9
0
def GetHwndIcon(hWnd):
    """
    Get a wx.Icon from a window through its hwnd window handle
    """
    hIcon = DWORD()
    res = SendMessageTimeout(
        hWnd, WM_GETICON, ICON_SMALL, 0, SMTO_ABORTIFHUNG, 1000, byref(hIcon)
    )

    if res == 0:
        hIcon.value = 0
    if hIcon.value < 10:
        hIcon.value = GetClassLong(hWnd, GCL_HICONSM)
        if hIcon.value == 0:
            res = SendMessageTimeout(
                hWnd,
                WM_GETICON,
                ICON_BIG,
                0,
                SMTO_ABORTIFHUNG,
                1000,
                byref(hIcon)
            )
            if res == 0:
                hIcon.value = 0
            if hIcon.value < 10:
                hIcon.value = GetClassLong(hWnd, GCL_HICON)
    if hIcon.value != 0:
        icon = wx.NullIcon
        value = hIcon.value
        # ugly fix for "OverflowError: long int too large to convert to int"
        if value & 0x80000000:
            value = -((value ^ 0xffffffff) + 1)
        icon.SetHandle(value)
        icon.SetSize((16, 16))
        return icon
    else:
        return None
def ReadPipeMessage(hPipe):
    data = ""
    fSuccess = 0
    chBuf = create_string_buffer(BUFSIZE)
    cbRead = DWORD(0)
    while not fSuccess:  # repeat loop if ERROR_MORE_DATA
        fSuccess = ReadFile(hPipe, chBuf, BUFSIZE, byref(cbRead), None)
        if fSuccess == 1:
            data += chBuf.value
            break
        elif GetLastError() != ERROR_MORE_DATA:
            break
        data += chBuf.value
    return loads(data)
Beispiel #11
0
def GetWindowProcessName(hWnd):
    dwProcessId = DWORD()
    GetWindowThreadProcessId(hWnd, byref(dwProcessId))
    return GetProcessName(dwProcessId.value)
Beispiel #12
0
def ExecAs(scriptPath, asAdministrator, funcName, *args, **kwargs):
    pipeName = "\\\\.\\pipe\\" + str(GUID.create_new())
    Msg("creating named pipe")
    hPipe = CreateNamedPipe(
        pipeName,
        PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
        PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
        PIPE_UNLIMITED_INSTANCES,
        BUFSIZE,
        BUFSIZE,
        0,
        None
    )
    if hPipe == INVALID_HANDLE_VALUE:
        raise Exception("Error in creating Named Pipe")
    overlapped = OVERLAPPED()
    overlapped.hEvent = CreateEvent(None, 1, 0, None)
    try:
        Msg("calling ConnectNamedPipe")
        ConnectNamedPipe(hPipe, byref(overlapped))
        localPath = dirname(__file__.decode('mbcs'))
        Msg("starting subprocess")
        hProcess = RunAs(
            abspath(join(localPath, "..", "..", "EventGhost.exe")),
            asAdministrator,
            "-execfile",
            GetUncPathOf(join(localPath, "PipedProcessClient.py")),
            pipeName,
            str(eg.debugLevel)
        )
        Msg("waiting for subprocess to connect")
        pHandles = (HANDLE * 2)(overlapped.hEvent, hProcess)
        ret = WaitForMultipleObjects(2, pHandles, 0, 25000)
        if ret == WAIT_OBJECT_0:
            # connect event
            Msg("got connect event")
        elif ret == WAIT_OBJECT_0 + 1:
            raise Exception("Unexpected end of subprocess.")
        elif ret == WAIT_TIMEOUT:
            raise Exception("Timeout in waiting for subprocess.")
        else:
            raise Exception("Unknown return value")

        Msg("sending startup message")
        WritePipeMessage(
            hPipe,
            MESSAGE_ARGS,
            (GetUncPathOf(scriptPath), funcName, args, kwargs)
        )
        chBuf = create_string_buffer(BUFSIZE)
        cbRead = DWORD(0)
        while True:
            fSuccess = ReadFile(hPipe, chBuf, BUFSIZE, byref(cbRead), None)
            if ((fSuccess == 1) or (cbRead.value != 0)):
                code, data = loads(chBuf.value)
                if code == MESSAGE_STDERR:
                    sys.stderr.write(data)
                elif code == MESSAGE_STDOUT:
                    sys.stdout.write(data)
                elif code == MESSAGE_RESULT:
                    result = data
                    break
                elif code == MESSAGE_EXCEPTION:
                    break
                else:
                    raise Exception("Unknown message type %r" % code)
        FlushFileBuffers(hPipe)
        DisconnectNamedPipe(hPipe)
    finally:
        CloseHandle(hPipe)
        CloseHandle(overlapped.hEvent)
    if code == MESSAGE_EXCEPTION:
        raise Exception("Child process raised an exception\n" + data)
    return result
Beispiel #13
0
def IsAdmin():
    """
    Find out if the user (the owner of the current process) is a member of
    the administrators group on the local computer (not on the domain!).
    """
    # First we must open a handle to the access token for this thread.
    hThread = HANDLE()
    if not OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, 0, byref(hThread)):
        err = GetLastError()
        if err == ERROR_NO_TOKEN:
            # If the thread does not have an access token, we'll examine the
            # access token associated with the process.
            if not OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY,
                                    byref(hThread)):
                raise WinError()
        else:
            raise WinError(err)
    # Then we must query the size of the group information associated with
    # the token. Note that we expect a FALSE result from GetTokenInformation
    # because we've given it a NULL buffer. On exit cbTokenGroups will tell
    # the size of the group information.
    cbTokenGroups = DWORD()
    if GetTokenInformation(hThread, TokenGroups, None, 0,
                           byref(cbTokenGroups)):
        raise WinError()

    # Here we verify that GetTokenInformation failed for lack of a large
    # enough buffer.
    err = GetLastError()
    if err != ERROR_INSUFFICIENT_BUFFER:
        raise WinError(err)

    # Now we allocate a buffer for the group information.
    ptg = create_string_buffer(cbTokenGroups.value)

    # Now we ask for the group information again.
    # This may fail if an administrator has added this account to an additional
    # group between our first call to GetTokenInformation and this one.
    if not GetTokenInformation(hThread, TokenGroups, ptg, cbTokenGroups,
                               byref(cbTokenGroups)):
        raise WinError()

    # Now we must create a System Identifier for the Admin group.
    systemSidAuthority = SID_IDENTIFIER_AUTHORITY()
    systemSidAuthority.Value[5] = SECURITY_NT_AUTHORITY
    psidAdmin = PSID()
    if not AllocateAndInitializeSid(
            byref(systemSidAuthority), 2, SECURITY_BUILTIN_DOMAIN_RID,
            DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, byref(psidAdmin)):
        raise WinError()

    # Finally we'll iterate through the list of groups for this access
    # token looking for a match against the SID we created above.
    ptg = cast(ptg, POINTER(TOKEN_GROUPS))
    groups = cast(ptg.contents.Groups, POINTER(SID_AND_ATTRIBUTES))
    isAdmin = False
    for i in range(ptg.contents.GroupCount):
        if EqualSid(groups[i].Sid, psidAdmin.value):
            isAdmin = True
            break
    # Before we exit we must explicitly deallocate the SID we created.
    FreeSid(psidAdmin)
    return isAdmin
Beispiel #14
0
def GetComPorts(availableOnly=True):
    """
    Scans the registry for serial ports and return a list of (port, desc, hwid)
    tuples.
    If availableOnly is true only return currently existing ports.
    """
    result = []
    stringBuffer = create_unicode_buffer(256)
    flags = DIGCF_DEVICEINTERFACE
    if availableOnly:
        flags |= DIGCF_PRESENT
    hdi = SetupDiGetClassDevs(byref(GUID_CLASS_COMPORT), None, 0, flags)
    if hdi == INVALID_HANDLE_VALUE:
        raise WinError()
    dwRequiredSize = DWORD()
    dwIndex = 0
    while True:
        did = SP_DEVICE_INTERFACE_DATA()
        did.cbSize = sizeof(did)

        if not SetupDiEnumDeviceInterfaces(
                hdi, None, byref(GUID_CLASS_COMPORT), dwIndex, byref(did)):
            err = GetLastError()
            if err != ERROR_NO_MORE_ITEMS:
                raise WinError(err)
            break

        # get the size
        if not SetupDiGetDeviceInterfaceDetail(hdi, byref(did), None, 0,
                                               byref(dwRequiredSize), None):
            # Ignore ERROR_INSUFFICIENT_BUFFER
            err = GetLastError()
            if err != ERROR_INSUFFICIENT_BUFFER:
                raise WinError(err)

        # allocate buffer
        class _SP_DEVICE_INTERFACE_DETAIL_DATA(Structure):
            _fields_ = [
                ('cbSize', DWORD),
                ('DevicePath', TCHAR * (dwRequiredSize.value - sizeof(DWORD))),
            ]

        idd = _SP_DEVICE_INTERFACE_DETAIL_DATA()
        idd.cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA)
        devinfo = SP_DEVINFO_DATA()
        devinfo.cbSize = sizeof(devinfo)
        if not SetupDiGetDeviceInterfaceDetail(
                hdi, byref(did),
                cast(byref(idd), PSP_DEVICE_INTERFACE_DETAIL_DATA),
                dwRequiredSize, None, byref(devinfo)):
            raise WinError()
        # hardware ID
        if not SetupDiGetDeviceRegistryProperty(
                hdi, byref(devinfo), SPDRP_HARDWAREID, None,
                cast(stringBuffer, PBYTE),
                sizeof(stringBuffer) - 1, None):
            # Ignore ERROR_INSUFFICIENT_BUFFER
            err = GetLastError()
            if err != ERROR_INSUFFICIENT_BUFFER:
                raise WinError(err)
        szHardwareID = stringBuffer.value
        # friendly name
        if not SetupDiGetDeviceRegistryProperty(
                hdi, byref(devinfo), SPDRP_FRIENDLYNAME, None,
                cast(stringBuffer, PBYTE),
                sizeof(stringBuffer) - 1, None):
            # Ignore ERROR_INSUFFICIENT_BUFFER
            err = GetLastError()
            if err != ERROR_INSUFFICIENT_BUFFER:
                raise WinError(err)
        szFriendlyName = stringBuffer.value
        portName = re.search(r"\((.*)\)", szFriendlyName).group(1)
        result.append((portName, szFriendlyName, szHardwareID))
        dwIndex += 1

    SetupDiDestroyDeviceInfoList(hdi)
    return result