How to display absolute path with device name of currently opened file - c++

The first two lines of this code showing file name excluding device name like /Document/temp but I want
to show also device name like L"\Device\Harddisk0\DR0\Document\temp. I am using this code to call ObQueryNameString routine but it is showing NULL.
Please tell me what is wrong with code. I think memory is not allocating
properly.
PFILE_OBJECT pFileObject = IoGetCurrentIrpStackLocation(Irp)->FileObject;
if (pFileObject)
{
DbgPrint("FileName : %wZ\n", pFileObject->FileName);
}
NTSTATUS status = STATUS_UNSUCCESSFUL;
OBJECT_NAME_INFORMATION objName = {0};
ULONG ReturnLength = 1024;
ObQueryNameString(DeviceObject, objName, sizeof(objName), ReturnLength);
DbgPrint("FileName : %wZ\n", &objName);

Have you considered using GetFullPathName function?
Refer to http://msdn.microsoft.com/en-us/library/aa364963%28VS.85%29.aspx for more accurate explanation what it does.

Related

TaskDialogIndirect is returning an unusual error code

I'm using TaskDialogIndirect to display prompts to the user. Normally this works just fine, but sometimes, after the program has been running for a while, it begins returning an error code that the MSDN entry does not list as being one of the error codes this function can return.
0x80040001 OLE_E_ADVF "Invalid advise flags"
I have checked all the inputs to the function against previous successful calls in the same run. Aside from differences in the string to be displayed, they are identical. (the strings are even the same length.)
// create task dialog struct
TASKDIALOGCONFIG tdc;
ZeroMemory(&tdc, sizeof(TASKDIALOGCONFIG));
tdc.cbSize = sizeof(tdc);
tdc.dwFlags = (((dwMessageBoxFlags & MB_OKCANCEL) == MB_OKCANCEL) ? TDF_ALLOW_DIALOG_CANCELLATION : 0) | TDF_POSITION_RELATIVE_TO_WINDOW;
tdc.hwndParent = hwndOwner;
tdc.hInstance = LGetHInstance();
tdc.pszContent = usrText.wsz;
tdc.pButtons = _pButtons;
tdc.cButtons = nButtons;
tdc.pszMainIcon = pszTaskDialogIcon;
tdc.pszWindowTitle = usrCaption.wsz;
tdc.nDefaultButton = nDefaultButton;
// display it now
int iButton = 0;
BOOL b = 0;
HRESULT hResult = TaskDialogIndirect(&tdc, &iButton, NULL, &b);
NEW INFORMATION
At the same time that TaskDialogIndirect stops behaving correctly, ShellExecute also stops working, as does CreateFile.
This was actually caused by an event handle leak elsewhere. When the available handles ran out, no more API calls which needed to create a handle could succeed. They did return a rather odd set of error codes though, none of which was "out of handles".

How to convert UnicodeString to BSTR?

I'm having a problem when calling OpenDatabase function (DAO). It's prototipe is:
virtual HRESULT STDMETHODCALLTYPE OpenDatabase(BSTR Name/*[in]*/, VARIANT Options/*[in,opt]*/,
VARIANT ReadOnly/*[in,opt]*/,
VARIANT Connect/*[in,opt]*/,
Dao_tlb::Database** ppDb/*[out,retval]*/) = 0; // [-1]
So, when I do this:
if(OpenDialog1->Execute() != true) return;
The selected filename is saved in OpenDialog1->FileName. Then I call the function above:
pDatabasePtr = pDBEngine->OpenDatabase(WideString(OpenDialog1->FileName).c_bstr(), myOpts, myRead, myCon);
and this works! But, the problem is when I try to set the filename to something else:
OpenDialog1->FileName = ParamStr(1); // OpenDatabase don't work in runtime - file not recognised!
or even set the filename inside a function:
pDatabasePtr = pDBEngine->OpenDatabase(WideString(L"SomeDB.mdb").c_bstr(), myOpts, myRead, myCon);
In both cases I get strange errors and never able to open a database. So, I probably convert UnicodeString/WideString to BSTR incorrectly.
So, why this function (OpenDatabase) works with
if(OpenDialog1->Execute() != true) return;
and does not work with
OpenDialog1->FileName = ParamStr(1);
How do I set the conversion correctly?
I found answer in here if anyone else needs it:
https://forums.embarcadero.com/thread.jspa?messageID=498776

SymEnumSourceFiles get incomplete file names

I was tring to use SymEnumSourceFiles to get the file name within the debugging module.But the file name as a parameter in the callback function seems incomplete. e.g. A file named"c:\program files\test\test.cpp" only showed "c:\program fi" in the FileName part of the PSOURCEFILE type parameter, and that's very wired.
Here is my code:
struct foo
{
static BOOL CALLBACK run( PSOURCEFILE pSourceFile, PVOID UserContext)
{
static TCHAR szFileName[MAX_PATH] = _T("");
if (_tcscmp(szFileName, pSourceFile->FileName))
{
_tcscpy(szFileName, pSourceFile->FileName);
}
return TRUE;
}
};
HANDLE hCurrentProcess = GetCurrentProcess();
SymInitialize(hCurrentProcess, NULL, FALSE);
DWORD64 BaseOfDll = SymLoadModule64(hCurrentProcess,
NULL,
(LPCSTR)_bstr_t(lpszFile),
NULL,0,0);
if(!SymEnumSourceFiles(hCurrentProcess, BaseOfDll, NULL, foo::run, (PVOID)pCallBack))
{
ATLTRACE(_T(__FUNCTION__) _T(" error:0x%x\n"), GetLastError());
}
SymUnloadModule64(hCurrentProcess, BaseOfDll);
SymCleanup(hCurrentProcess);
Can anyone tell me where I go wrong please?
PS. When I simply replace SymEnumSourceFiles with SymEnumLines and change the callback function, the file name I got is correct.
There used to be a bug with SymEnumSymbols where symbol name was not zero terminated, maybe this one is related. Try zeroing out the filename after copying it (pSourceFile->FileName[0] = 0;).
Try ANSI version of SymEnumSourceFiles. There seems to be a bug in SymEnumSourceFilesW function.

How to check whether inserted SD Card is write protected or not in Qt?

Hi friends I am working on an application where I should check the file system of the SD card and also I need to check whether the SD card inserted is write protected or not. I was successful in getting the file system details as follows:
TCHAR volumeName[MAX_PATH + 1] = { 0 };
TCHAR fileSystemName[MAX_PATH + 1] = { 0 };
DWORD serialNumber = 0;
DWORD maxComponentLen = 0;
DWORD fileSystemFlags = 0;
LPCWSTR path = deviceData->m_strPath.utf16(); // deviceData gives me the path of the SD Card
// Get the file system details
if (GetVolumeInformation(
path,
volumeName,
ARRAYSIZE(volumeName),
&serialNumber,
&maxComponentLen,
&fileSystemFlags,
fileSystemName,
ARRAYSIZE(fileSystemName)))
{
newData.strFileSystem = QString::fromUtf16(fileSystemName);
}
m_SDInfoList.append(newData); // m_SDInfoList is QList
With this approach I get to know whether the file system is FAT32 or NTFS. Now I want to achieve the write protected details. Is their a Qt API that can gimme whether the inserted SD Card is write protected or not??? Please help :)
Update:
This is what I did using QFileInfo:
QFileInfo fileInfo(deviceData->m_strPath);
if(!fileInfo.isWritable())
{
newData.strStatus = "WriteProtect Enabled";
}
else
{
newData.strStatus = "WriteProtect Disabled";
}
It always ends up giving me WriteProtect Disable even though I have set the write protected permission.
I suspect you can't do that with Qt. You'll need to add custom code for each target platform.
However, you can simply try to create an empty file and then immediately delete it. If creating the file fails then the volume is likely read only (or it has ran out of free space, you'll need to check the error codes to be sure).
Not sure about how to do it in QT, but WinAPI provides you with GetVolumeInformation (http://pinvoke.net/default.aspx/kernel32/GetVolumeInformation.html) method (allows you to check weather drive is write protected or not), that returns the following flag:
/// <summary>
/// The specified volume is read-only.
/// </summary>
ReadOnlyVolume = 0x80000,

Using RegQueryValueEx and HKEY_PERFORMANCE_COUNTER to Get "Disk Bytes/sec%

I've looked for examples and documentation, but I still can't figure this out...
How do you use RegQueryValueEx (not the PdhXxx functions) to query for something like Disk Bytes/sec?
I've tried the following:
DWORD type;
static union { TCHAR Data[32 * 1024]; PERF_DATA_BLOCK Perf; } perf;//Stack buffer
DWORD cbData = sizeof(perf);
LSTATUS s = RegQueryValueEx(HKEY_PERFORMANCE_DATA,
_T("PhysicalDisk"), NULL, &type, (LPBYTE)&perf, &cbData);
PPERF_OBJECT_TYPE pObjType =
(PPERF_OBJECT_TYPE)((BYTE*)&perf + perf.Perf.HeaderLength);
but it just returns a header with no data. :(
You can't query for the data by name like that. Instead, you need to query by index. MSDN can help you with some code to find out the appropriate index to query. Unfortunately, you need to make the determination of which index at run-time.
For example, the following SHOULD retrieve the performance data for the processor.
LSTATUS s = RegQueryValueEx(HKEY_PERFORMANCE_DATA, _T("238"), NULL,
&type, (LPBYTE)&perf, &cbData);