psutil_proc_username(PyObject *self, PyObject *args) {
    long pid;
    HANDLE processHandle = NULL;
    HANDLE tokenHandle = NULL;
    PTOKEN_USER user = NULL;
    ULONG bufferSize;
    WCHAR *name = NULL;
    WCHAR *domainName = NULL;
    ULONG nameSize;
    ULONG domainNameSize;
    SID_NAME_USE nameUse;
    PyObject *py_username = NULL;
    PyObject *py_domain = NULL;
    PyObject *py_tuple = NULL;

    if (! PyArg_ParseTuple(args, "l", &pid))
        return NULL;

    processHandle = psutil_handle_from_pid(
        pid, PROCESS_QUERY_LIMITED_INFORMATION);
    if (processHandle == NULL)
        return NULL;

    if (!OpenProcessToken(processHandle, TOKEN_QUERY, &tokenHandle)) {
        PyErr_SetFromOSErrnoWithSyscall("OpenProcessToken");
        goto error;
    }

    CloseHandle(processHandle);
    processHandle = NULL;

    // Get the user SID.
    bufferSize = 0x100;
    while (1) {
        user = malloc(bufferSize);
        if (user == NULL) {
            PyErr_NoMemory();
            goto error;
        }
        if (!GetTokenInformation(tokenHandle, TokenUser, user, bufferSize,
                                 &bufferSize))
        {
            if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
                free(user);
                continue;
            }
            else {
                PyErr_SetFromOSErrnoWithSyscall("GetTokenInformation");
                goto error;
            }
        }
        break;
    }

    CloseHandle(tokenHandle);
    tokenHandle = NULL;

    // resolve the SID to a name
    nameSize = 0x100;
    domainNameSize = 0x100;
    while (1) {
        name = malloc(nameSize * sizeof(WCHAR));
        if (name == NULL) {
            PyErr_NoMemory();
            goto error;
        }
        domainName = malloc(domainNameSize * sizeof(WCHAR));
        if (domainName == NULL) {
            PyErr_NoMemory();
            goto error;
        }
        if (!LookupAccountSidW(NULL, user->User.Sid, name, &nameSize,
                               domainName, &domainNameSize, &nameUse))
        {
            if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
                free(name);
                free(domainName);
                continue;
            }
            else {
                PyErr_SetFromOSErrnoWithSyscall("LookupAccountSidW");
                goto error;
            }
        }
        break;
    }

    py_domain = PyUnicode_FromWideChar(domainName, wcslen(domainName));
    if (! py_domain)
        goto error;
    py_username = PyUnicode_FromWideChar(name, wcslen(name));
    if (! py_username)
        goto error;
    py_tuple = Py_BuildValue("OO", py_domain, py_username);
    if (! py_tuple)
        goto error;
    Py_DECREF(py_domain);
    Py_DECREF(py_username);

    free(name);
    free(domainName);
    free(user);

    return py_tuple;

error:
    if (processHandle != NULL)
        CloseHandle(processHandle);
    if (tokenHandle != NULL)
        CloseHandle(tokenHandle);
    if (name != NULL)
        free(name);
    if (domainName != NULL)
        free(domainName);
    if (user != NULL)
        free(user);
    Py_XDECREF(py_domain);
    Py_XDECREF(py_username);
    Py_XDECREF(py_tuple);
    return NULL;
}