WCHAR to LPCWSTR - c++

when i use CreateFile function like below ...it gives me valid handle
HANDLE hDevice = CreateFile (TEXT("\\\\.\\G:"),
0,FILE_SHARE_READ | FILE_SHARE_WRITE, // share mode
NULL, OPEN_EXISTING, 0, NULL);
if( hDevice == INVALID_HANDLE_VALUE )
{
qDebug()<<"In valid handle";
}
else
{
qDebug()<<"valid handle";
}
when i use like below ...it gives me invalid handle..
WCHAR Drive[4];
qDebug ()<<QString::fromWCharArray ( Drive );
The above prints like "G:\"
HANDLE hDevice = CreateFile ( Drive,
0,FILE_SHARE_READ | FILE_SHARE_WRITE, // share mode
NULL, OPEN_EXISTING, 0, NULL);
if( hDevice == INVALID_HANDLE_VALUE )
{
qDebug()<<"In valid handle";
}
else
{
qDebug()<<"valid handle";
}
How can i change the wchar to LPCWSTR
Thank you

The problem is not the conversion of the string, but the contents of the string. You can't open a volume (I guess that's what you're trying to do) with "G:\". It needs to be in the same format as you used in the first example. From MSDN:
When opening a volume or floppy drive,
the lpFileName string should be the
following form: \\.\X:. Do not use a
trailing backslash, which indicates
the root directory of a drive.
Hint: Always use GetLastError() after API functions fail to get the reason for the failure.
Update:
MSDN Link

You can either use the toWCharArray function or try something like this:
handle = CreateFile((LPCWSTR) fileName.constData(), FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0);
or this:
handle = CreateFile((LPCWSTR) fileName.utf16(), FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0);

LPCWSTR is a pointer (LP) to a constant (C) wide character (W) string (STR). In other words, this is a const WCHAR*
WCHAR Drive[4]; is a wide character array, which can also be called a wide character string.
Any array of a certain type can implicitly convert to a pointer to that same type. Furthermore, a pointer of a certain type can implicitly convert to a constant pointer of the same type, especially in the case of a function call.
Thus passing Drive to that function implicitly converts to LPCWSTR.
Your problem in not in that conversion. Your problem is most likely in the contents of your strings, as humbagumba's answer already explained.

Related

C++ Overwriting Contents of a Handle

I am trying to get a number from a HANDLE file, store it in an int, and possibly replace it in the same file. My code right now looks like this
HANDLE numFile = INVALID_HANDLE_VALUE; //Just in case file not found
numFile = CreateFile("numFile.txt",
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
ReadFile(numFile, input, sizeof(char), &bytesRead, NULL);
int myNumber = input[0];
I know that there exists a WriteFile method in the API, but it looks like it will append the file as opposed to overwriting the contents. I have briefly considered deleting and recreating the file each time, but this seems unnecessarily complex for this problem. Any ideas out there?
Use the function SetFilePointer prior WriteFile for moving back to the begin
SetFilePointer(numFile, 0, NULL, FILE_BEGIN);

DeviceIoControl assistance

Using C++, trying to use DeviceIOControl to send mouse clicks directly through driver. Very little documentation seems to exist on this. Very annoying. This is all I figured out so far. Have no idea what goes into any parameter after dwIoControlNode. I've seen keyboard examples, but no mouse ones.
EDIT: Appreciate your help Remy, will try your suggestions tomorrow, been working on this all day and am braindead.
int i = 0;
GUID MouseyBoi;
HANDLE HIDD = NULL;
HIDD_ATTRIBUTES DeviceAttributes;
ULONG Needed, l;
HDEVINFO DeviceInfoSet;
SP_DEVICE_INTERFACE_DATA DevData;
PSP_INTERFACE_DEVICE_DETAIL_DATA DevDetail;
PSP_DEVICE_INTERFACE_DATA InfData;
DeviceInfoSet = SetupDiGetClassDevs(&GUID_DEVCLASS_MOUSE, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
SetupDiGetDeviceInterfaceDetail(DeviceInfoSet, &DevData, NULL, 0, &Needed, 0);
DevDetail = (SP_DEVICE_INTERFACE_DETAIL_DATA*)GlobalAlloc(GPTR, 1 + 4);
DevDetail->cbSize = sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA);
HIDD = CreateFile(DevDetail->DevicePath, GENERIC_WRITE, NULL, NULL, OPEN_EXISTING, 0, NULL);
HidD_GetAttributes(HIDD, &DeviceAttributes);
std::cout << DeviceAttributes.VersionNumber << std::endl;
std::cout << DeviceAttributes.ProductID;
First off, you need to escape \ characters in a string literal, eg:
LPCWSTR FileName = L"USB\\VID_046D&PID_C07E&MI_00\\6&361cde46&0&0000";
And second, this is not a valid file/device path that you can open with CreateFile() anyway. It should look more like this:
LPCWSTR FileName = L"\\\\?\\USB#VID_046D&PID_C07E&MI_00#6&361cde46&0&0000#{<guid>}";
You can use SetupDiGetDeviceInterfaceDetail() to get a device path that CreateFile() will accept.
That being said, once you do manage to open a handle to the USB device, the DeviceIoControl() call should look like the following, since you are just inserting input data, not getting any output back out (but I could be wrong, as there is no documentation for IOCTL_MOUSE_INSERT_DATA that I can find):
MOUSE_INPUT_DATA MouseInput = {};
MouseInput.UnitId = 0;
MouseInput.ButtonFlags = MOUSE_LEFT_BUTTON_DOWN;
// set other fields as needed ...
DeviceIoControl(hFile, IOCTL_MOUSE_INSERT_DATA, &MouseInput, sizeof(MOUSE_INPUT_DATA), NULL, 0, NULL, NULL);

CreateFile returns error INVALID_HANDLE_VALUE (for COM port), and GetLastError returns "can't find file specified"

I'm opening a port to communicate with a device and control the device, but the CreateFile() function returns INVALID_HANDLE_VALUE.
GetLastError() returns 2 which means it can't find the specified file.
My code is shown below:
wsprintf( szPort, "COM%d", nPort );
m_hIDComDev = CreateFile(szPort,
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
NULL);
if (m_hIDComDev == INVALID_HANDLE_VALUE)
{
DWORD err=GetLastError();
}
Why does this problem occur?
The problem is that you're not specifying the correct value for lpFileName for your serial port. You should be using this format:
"\\\\.\\COM%d"
Which will result in a string that looks like \\.\COM1, which is the correct format.
Try using
char *szPort = _T("COM1"); // Change port number to your unused existing port
_T forces to keep szPort in ASCII.

Write to a txt file using windows API

I am trying to write some lines to a a txt file through an ATL application. Below is the fragment of code I use:
HANDLE hFile = CreateFile(ofn.lpstrFile,
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL);
DWORD dwBytesWritten = 0;
std::list<CString> helpList;
std::list<CString>::iterator it;
helpList.push_back(L"First Line\r\n");
helpList.push_back(L"Second Line");
for(it=helpList.begin(); it!=helpList.end(); ++it)
WriteFile( hFile, (*it).GetString(), (*it).GetLength(), &dwBytesWritten, NULL );
CloseHandle(hFile);
Notwithstanding everything is working right, nothing is finally written to the file. What should I change in the code?
Couple of issues:
Close the handle to the file using CloseHandle()
The length argument for WriteFile() is in bytes but you're specifying characters. Since you're using wide chars you need to multiple the length value by the size of the char.

Why does CreateFile return invalid handle?

I have CreateFile() to create a hidden file type but the problem that it keeps returning invalid handle.
file = CreateFileW(_T("hey.txt"),
GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
0, 0);
error = GetLastError();
WriteFile(file, buff, sizeof(buff),
&dwRet, NULL);
Any idea?
It would probably be best if you showed the exact code that you're using including all the error checking, and how you do it, is important (especially in the case of this question)...
The correct error checking for your code should be something more like...
file = CreateFile(_T("hey.txt"), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0);
if (file == INVALID_HANDLE_VALUE)
{
const DWORD error = GetLastError();
// Do something!
}
else
{
if (!WriteFile(file, buff, sizeof(buff), &dwRet, NULL))
{
const DWORD error = GetLastError();
// Do something!
}
}
You should only be checking for an error if you get a return value of INVALID_FILE_HANDLE as CreateFile() might not reset the last error before it starts and so you might get spurious error values from GetLastError() if the function succeeds...
A last error of 6, ERROR_INVALID_HANDLE, is unusual from CreateFile() unless you're using the template file parameter, which you're not...
Your code using CreateFileW and _T("") is incorrect and wont compile in a non unicode build. Better to use CreateFile and _T("") or CreateFileW and L"".
Your code will not create a hidden file, see molbdnilo's answer.
0 is not a valid parameter for dwFlagsAndAttributes. To create a hidden file, pass FILE_ATTRIBUTE_HIDDEN.
If "C:\test.txt" exists and is hidden, then following code fails (h = INVALID_HANDLE_VALUE) :
h = CreateFile("C:\\test.txt", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0);
this fails too (argument 6 == FILE_ATTRIBUTES_NORMAL or argument6 == 0 seems so be the same) :
h = CreateFile("C:\\test.txt", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
but this works :
h = CreateFile("C:\\test.txt", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_HIDDEN, 0);
So roughly in other words :
if the file already exists and is hidden then CreateFile with "CREATE_ALWAYS" fails if argument 6 != FILE_ATTRIBUTE_HIDDEN.