Skip to content

Instantly share code, notes, and snippets.

@zooba
Created May 24, 2022 22:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zooba/e34aae1bea14bf3915a0ad068a9ecdc6 to your computer and use it in GitHub Desktop.
Save zooba/e34aae1bea14bf3915a0ad068a9ecdc6 to your computer and use it in GitHub Desktop.
Saving my read_usn method in case I want it later
// FILE_ID.Identifier is BYTE[16] containing a single 128-bit unsigned integer
static PyObject *
_PyLong_From_FILE_ID(FILE_ID_128 *id)
{
PyObject *low = PyLong_FromUnsignedLongLong(
*(unsigned long long*)&id->Identifier[0]
);
if (!low) {
return NULL;
}
PyObject *number = PyLong_FromUnsignedLongLong(
*(unsigned long long*)&id->Identifier[8]
);
if (number) {
Py_SETREF(number, _PyLong_Lshift(number, 64));
}
if (number) {
Py_SETREF(number, _PyLong_Add((PyLongObject *)number, (PyLongObject *)low));
}
Py_DECREF(low);
return number;
}
/*[clinic input]
_winapi.read_usn
path: LPCWSTR
Efficiently reads the USN number for the specified path.
[clinic start generated code]*/
static PyObject *
_winapi_read_usn_impl(PyObject *module, LPCWSTR path)
/*[clinic end generated code: output=9a744a78b72e3fcf input=cfcf31cb44d0a9c7]*/
{
HANDLE hFile;
int err = 0;
union {
unsigned char buffer[32678];
USN_RECORD_COMMON_HEADER hdr;
USN_RECORD_V2 v2;
USN_RECORD_V3 v3;
USN_RECORD_V4 v4;
} usn;
memset(&usn.hdr, 0, sizeof(usn.hdr));
Py_BEGIN_ALLOW_THREADS;
hFile = CreateFileW(
path,
FILE_READ_ATTRIBUTES,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
NULL,
OPEN_EXISTING,
0,
NULL
);
if (hFile != INVALID_HANDLE_VALUE) {
DWORD bytesReturned = 0;
if (!DeviceIoControl(
hFile,
FSCTL_READ_FILE_USN_DATA,
NULL, 0, // no input data
usn.buffer, sizeof(usn), // output data
&bytesReturned,
NULL
)) {
err = GetLastError();
}
CloseHandle(hFile);
} else {
err = GetLastError();
}
Py_END_ALLOW_THREADS;
if (err) {
PyErr_SetFromWindowsErr(err);
return NULL;
}
PyObject *number = NULL;
if (usn.hdr.MajorVersion == 2) {
number = PyLong_FromUnsignedLongLong(usn.v2.FileReferenceNumber);
} else if (usn.hdr.MajorVersion == 3) {
number = _PyLong_From_FILE_ID(&usn.v3.FileReferenceNumber);
} else if (usn.hdr.MajorVersion == 4) {
number = _PyLong_From_FILE_ID(&usn.v4.FileReferenceNumber);
} else {
number = Py_None;
Py_INCREF(number);
}
if (!number) {
return NULL;
}
return Py_BuildValue("(hhN)", usn.hdr.MajorVersion, usn.hdr.MinorVersion, number);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment