DVD or CD Player? - c++

I want to know if my player is a DVD or CD Player, etc ...
I tried :
SELECT Drive, MediaType, Caption FROM Win32_CDROMDrive
MediaType doesn't work on XP, and not very well on Seven.
I tried on a computer (with Windows 7) with 1 player (Cd Writer/DVD-ROM) in MediaType I found Cd Writer.
Second solution :
I search in "Caption" if I find "DVD"
I tried a software, (SIW - System Information for Windows) and in my Player properties :
Capabilities :
CD Reader : CD ROM, CD R, CD RW
CD Writer : CD R, CD RW
DVD Reader : DVD ROM, DVD R, DVD RW, DVD RAM
DVD Writer : No
SMART Support : No
So, I want to know : with a WMI query (or other solution, I use C++), can I have the same informations or not?
It would be awesome if I could! If I can't, I just keep my "String parsing".

to determine if a drive is DVD or CDROM , you can use the the DeviceIoControl function with the IOCTL_STORAGE_GET_MEDIA_TYPES_EX control code and then check the value of the DeviceType field of the GET_MEDIA_TYPES structure.
Try this sample
#include "stdafx.h"
#include <windows.h>
#include <winioctl.h>
#include <stdio.h>
#include <iostream>
using namespace std;
#define wszDrive L"\\\\.\\D:"
int wmain(int argc, wchar_t *argv[])
{
BOOL bResult;
HANDLE hDevice = INVALID_HANDLE_VALUE; // handle to the drive to be examined
hDevice = CreateFileW(wszDrive, // drive to open
GENERIC_READ,
FILE_SHARE_READ | // share mode
FILE_SHARE_WRITE,
NULL, // default security attributes
OPEN_EXISTING, // disposition
0, // file attributes
NULL); // do not copy file attributes
if (hDevice == INVALID_HANDLE_VALUE) // cannot open the drive
{
return (FALSE);
}
UCHAR lpOutBuffer[2048];
DWORD nOutBufferSize = sizeof(lpOutBuffer);
ULONG lpBytesReturned;
bResult = DeviceIoControl(hDevice, // device to be queried
IOCTL_STORAGE_GET_MEDIA_TYPES_EX, // operation to perform
NULL, 0, // no input buffer
&lpOutBuffer, nOutBufferSize, &lpBytesReturned,
NULL);
CloseHandle(hDevice);
PGET_MEDIA_TYPES pMediaTypes = (PGET_MEDIA_TYPES) lpOutBuffer;
if (bResult)
{
if (pMediaTypes->DeviceType==FILE_DEVICE_DVD)
{
wprintf(L"DVD\n");
}
else
if (pMediaTypes->DeviceType==FILE_DEVICE_CD_ROM)
{
wprintf(L"CDROM\n");
}
}
else
{
wprintf (L"Failed. Error %ld.\n", GetLastError ());
}
cin.get();
return ((int)bResult);
}

Related

Writing to .txt with WriteFile() C++

(Using C++, Windows 10, Microsoft Visual Studio 2017)
Hello, I am new to serial ports but trying to learn how to open, close, read, and write with them
Right now, I am trying to use the CreateFile() and WriteFile() functions to write to a txt file.
I created a .txt file called "write.txt" and saved it in my Documents folder. Then I added it to my project's source files via "Add" --> "Existing Item". The file is empty.
I wrote the program below, hoping I could write to the file, but after running then checking on the file, the file is still empty. The program compiles but I am guessing I have an error somewhere. Am I going about writing to a file correctly?
#include <iostream>
#include <Windows.h>
#include <string>
using namespace std;
int main() {
HANDLE write;
write = CreateFile(TEXT("\\write.txt"), GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (write == INVALID_HANDLE_VALUE) {
DWORD errorWrite = GetLastError();
printf("Error in opening file\n");
printf("Error = 0x%x\n", errorWrite);
}
else {
printf("Opening file successful\n");
}
WriteFile(write, "hello", 5, 0, 0);
CloseHandle(write);
return 0;
}
The output says the file was opened successfully, but the write.txt file remains empty. Any advice?
Thank you in advance :D
You are not accessing the text file that is located in your Documents folder. You are accessing a text file that is located at the root of the drive where the calling process's current working directory is currently pointing at.
You need to explicitly query the OS for the path to the Documents folder (ie, via SHGetFolderPath() or SHGetKnownFolderPath()), and then append your filename to that path.
Also, you are calling WriteFile() incorrectly. In particular, the lpNumberOfBytesWritten parameter is wrong:
lpNumberOfBytesWritten
A pointer to the variable that receives the number of bytes written when using a synchronous hFile parameter. WriteFile sets this value to zero before doing any work or error checking. Use NULL for this parameter if this is an asynchronous operation to avoid potentially erroneous results.
This parameter can be NULL only when the lpOverlapped parameter is not NULL.
And, you are not doing any error handling on WriteFile(), either:
If the function succeeds, the return value is nonzero (TRUE).
If the function fails, or is completing asynchronously, the return value is zero (FALSE). To get extended error information, call the GetLastError function.
Try something more like this instead:
#include <iostream>
#include <string>
#include <Windows.h>
#include <Shlobj.h>
#include <shlwapi.h>
using namespace std;
int main() {
TCHAR path[MAX_PATH] = {};
HRESULT hRes = SHGetFolderPath(NULL, CSIDL_MYDOCUMENTS, NULL, SHGFP_TYPE_CURRENT, path);
if (FAILED(hRes)) {
printf("Can't get Documents folder path\nError = 0x%08x\n", hRes);
}
else {
PathAppend(path, TEXT("write.txt"));
HANDLE write = CreateFile(path, GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (write == INVALID_HANDLE_VALUE) {
DWORD errorWrite = GetLastError();
printf("Can't open file\nError = %u\n", errorWrite);
}
else {
printf("File opened successful\n");
DWORD written;
if (!WriteFile(write, "hello", 5, &written, NULL)) {
DWORD errorWrite = GetLastError();
printf("Can't write to file\nError = %u\n", errorWrite);
} else {
printf("File written successful\n");
}
CloseHandle(write);
}
}
return 0;
}

Dll Injector not detecting Dll

I recently coded an injector where as long as the dll is in the same directory as the exe injector it will inject but even when the dLL is in the same path it still returns with the error file not found.
Very new to c++ so not exactly sure how to fix it, only this I know that the problem must lie in the dll_name
The c++ code is listed here
#include <Windows.h>
#include <string>
#include <thread>
#include <libloaderapi.h>
using namespace std;
void get_proc_id(const char* window_title, DWORD &process_id)
{
GetWindowThreadProcessId(FindWindow(NULL, window_title), &process_id); // Find Process ID by using title of window
}
void error(const char* error_title, const char* error_message)
{
MessageBox(NULL, error_message, error_title, NULL);
exit(-1);
//if error occurs output false
}
bool file_exists(string file_name) // Makes sure file exists
{
struct stat buffer;
return (stat(file_name.c_str(), &buffer) == 0);
//Information goes through buffer if = 0 , it worked
//Creates random buffer of stat sturc doesnt matter what goes in - making sure function is successful, gets info about file and checks if it workeed
}
int main()
{
DWORD proc_id = NULL;
char dll_path[MAX_PATH];
const char* dll_name = "TestDll2.dll"; //Name of Dll
const char* window_title = "Untitled - Paint"; //Must Match Title Name
if (!file_exists(dll_name));
{
error("file_exists", "File does not exist");
}
if (!GetFullPathName(dll_name, MAX_PATH, dll_path, nullptr))
{
error("GetFullPathName", "Failed to get full file path");
}
get_proc_id(window_title, proc_id);
if (proc_id == NULL)
{
error("get_proc_id", "Failed to get process ID");
}
HANDLE h_process = OpenProcess(PROCESS_ALL_ACCESS, NULL, proc_id);
if (!h_process)
{
error("OpenProcess", "Failed to open handle to process");
}
void* allocated_memory = VirtualAllocEx(h_process, nullptr, MAX_PATH, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); //Calling Virutal Allocation, passing handle to process - reserving memory by going thru reserve and need to commit to it so we can write
if (!allocated_memory)
{
error("VirtualAllocEx", "Failed to allocate memory");
}
if (!WriteProcessMemory(h_process, allocated_memory, dll_path, MAX_PATH, nullptr)) // Write DLL path into the target program
{
error("WriteProcessMemory", "Failed to write process memory");
}
//If above works we call loadlibarya which is where the dll is stored
HANDLE h_thread = CreateRemoteThread(h_process, nullptr, NULL, LPTHREAD_START_ROUTINE(LoadLibraryA), allocated_memory, NULL, nullptr);
if (!h_thread)
{
error("CreateRemoteThread", "Failed to create remote thread");
}
CloseHandle(h_process);
VirtualFreeEx(h_process, allocated_memory, NULL, MEM_RELEASE);
MessageBox(0, "Successfully Injected!", "Sucess", 0);
} ```
Try to use C++ STL function or Windows native API:
#include <string>
#include <filesystem>
#include <Shlwapi.h>
#pragma comment(lib, "Shlwapi.lib")
bool IsExists(const std::string &FilePathName)
{
return std::filesystem::exists(FilePathName);
}
bool IsExists(const std::string &FilePathName)
{
return PathFileExistsA(FilePathName.c_str());
}
The file is being searched in the current directory, not in the directory of the exe file. These might not be the same. You have to find the path to the exe file in order to search for files in its directory. On Windows you could do something like this:
#include <psapi.h>
// ....
HANDLE Handle = OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
FALSE, GetCurrentProcessId() );
if ( Handle ) {
TCHAR buffer[MAX_PATH];
if ( GetModuleFileNameEx( Handle, 0, buffer, MAX_PATH ) ) {
std::filesystem::path exePath( buffer ); // TODO this might need encoding conversion
auto exeDir = exePath.parent_path();
auto dllPath = exeDir / "TestDll2.dll";
if ( std::filesystem::exists( dllPath ) ) {
// ...
}
}
}
You can also try GetProcessImageFileName if GetModuleFileNameEx does not work. Apparently it does not work in 32-bit applications on a 64-bit system (see comments in this answer).

Getting Directory Size by reading through the MFT in C++ (like TreeSize)

Please read before quoting “repost” - I am aware similar questions have been asked, but I am yet to find a satisfactory answer
My goal is to provide a tree-like directory structure of disk space usage allowing the user to drill down the hierarchy in order to locate sizable folders.
The program TreeSize is an excellent example of this, and I am looking to get the same response times as this program.
My current code can iterate through my 480GB of files in aprx 25 seconds using the MFT. I am looking from this point to start building directory sizes by getting the file information (MFT contains only fileName and parentId, not full file path)
To get file information from MFT journal entry my current code calls
TCHAR filePath[MAX_PATH];
HANDLE hh = OpenFileById(hDevice, &(getFileIdDescriptor(pRecord->FileReferenceNumber)), 0, 0, 0, 0);
GetFinalPathNameByHandle(hh, filePath, MAX_PATH, 0);
Unfortunately this code increases the overall execution time of the program from 25 seconds to 5 minutes.
Is there a better way to get the file information?
Many thanks if you suggest FindFirstFile and FindNextFile but for processing large directories these options are too slow
Code as below (I’m not a C programmer as you might notice!)
#include <iostream>
#include <string>
#include <fstream>
#include <windows.h>
#include <fstream>
#include <atlbase.h>
#include <windows.h>
#include <stdio.h>
using namespace std;
typedef std::basic_string<TCHAR> tstring;
FILE_ID_DESCRIPTOR getFileIdDescriptor(const DWORDLONG fileId)
{
FILE_ID_DESCRIPTOR fileDescriptor;
fileDescriptor.Type = FileIdType;
fileDescriptor.FileId.QuadPart = fileId;
fileDescriptor.dwSize = sizeof(fileDescriptor);
return fileDescriptor;
}
bool ReadMFT()
{
HANDLE hDevice = CreateFile(TEXT("\\\\.\\C:"),
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
0,
OPEN_EXISTING,
FILE_FLAG_OVERLAPPED,
0);
if (hDevice == INVALID_HANDLE_VALUE) // cannot open the drive
{
printf("Error %d", GetLastError());
return (FALSE);
}
USN_JOURNAL_DATA ujd = { 0 };
DWORD cb = 0;
BYTE pData[sizeof(DWORDLONG) + 0x10000] = { 0 };
if (!DeviceIoControl(hDevice, FSCTL_QUERY_USN_JOURNAL, NULL, 0, &ujd, sizeof(USN_JOURNAL_DATA), &cb, NULL))
{
printf("Error %d", GetLastError());
return (FALSE);
}
MFT_ENUM_DATA med = { 0 };
med.StartFileReferenceNumber = 0;
med.LowUsn = 0;
med.HighUsn = ujd.NextUsn;
while (TRUE)
{
if (!DeviceIoControl(hDevice, FSCTL_ENUM_USN_DATA, &med, sizeof(med), pData, sizeof(pData), &cb, NULL))
{
printf("Error %d", GetLastError());
break;
}
PUSN_RECORD pRecord = (PUSN_RECORD)&pData[sizeof(USN)];
//Inner Loop
while ((PBYTE)pRecord < (pData + cb))
{
tstring sz((LPCWSTR)
((PBYTE)pRecord + pRecord->FileNameOffset),
pRecord->FileNameLength / sizeof(WCHAR));
pRecord = (PUSN_RECORD)((PBYTE)pRecord + pRecord->RecordLength);
// *******************************************************************************
// APPROACH 1
// Adding these lines of code increases the time from 25 seconds to 340 seconds
// Although it may be possible to push this onto a queue and run these in parrallel
// I still think it's an expensive option
/*TCHAR filePath[MAX_PATH];
HANDLE hh = OpenFileById(hDevice, &(getFileIdDescriptor(pRecord->FileReferenceNumber)), 0, 0, 0, 0);
GetFinalPathNameByHandle(hh, filePath, MAX_PATH, 0);*/
}
med.StartFileReferenceNumber = *(DWORDLONG *)pData;
}
}
int main()
{
ReadMFT();
}
Many thanks
After a few trials and errors, running the
FILE_ID_DESCRIPTOR f = getFileIdDescriptor(pRecord->FileReferenceNumber);
q.Dispatch(f, [f]
{
TCHAR filePath[MAX_PATH];
HANDLE hh = OpenFileById(hDevice, (LPFILE_ID_DESCRIPTOR)&(f), 0, 0, 0, 0);
GetFinalPathNameByHandle(hh, filePath, MAX_PATH, 0);
});
in parrallel brings the time down to 1:30
Check out this guys dispatch queue implementation
https://github.com/embeddedartistry/embedded-resources/blob/master/examples/cpp/dispatch.cpp
You might want to iterate the $INDEX_ALLOCATION attribute to get a list of the child nodes.

Attempting to open CD tray

I'm trying to open and close the CD tray of my computer using a piece of code. I have been using MCI commands and have included winmm.lib in the additional dependencies of my project configuration. I've included windows.h and mmsystem.h as well.
The code I'm using is as follows:
mciSendCommand(0, MCI_SET, MCI_SET_DOOR_OPEN, NULL);
mciSendCommand(1, MCI_SET, MCI_SET_DOOR_CLOSED, NULL);
The code builds and runs fine, there's just no CD tray action going on! Can anyone suggest how I need to adapt this?
If you have multiple CD-Drives you should use the following code:
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
int _tmain()
{
DWORD dwBytes;
HANDLE hCdRom = CreateFile(_T("\\\\.\\M:"), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
if (hCdRom == INVALID_HANDLE_VALUE)
{
_tprintf(_T("Error: %x"), GetLastError());
return 1;
}
// Open the door:
DeviceIoControl(hCdRom, IOCTL_STORAGE_EJECT_MEDIA, NULL, 0, NULL, 0, &dwBytes, NULL);
Sleep(1000);
// Close the door:
DeviceIoControl(hCdRom, IOCTL_STORAGE_LOAD_MEDIA, NULL, 0, NULL, 0, &dwBytes, NULL);
CloseHandle(hCdRom);
}
You are missing some steps, first you need to open the device.
Try this:
#pragma comment( lib, "winmm.lib" )
#include "stdafx.h"
#include <Windows.h>
#include <mmsystem.h>
int _tmain()
{
MCI_OPEN_PARMS mPar = { 0 };
mPar.lpstrDeviceType = reinterpret_cast<LPCWSTR>(MCI_DEVTYPE_CD_AUDIO);
// Open device
mciSendCommand(0, MCI_OPEN, MCI_OPEN_TYPE | MCI_OPEN_TYPE_ID, (DWORD)&mPar);
// Open tray
mciSendCommand(mPar.wDeviceID, MCI_SET, MCI_SET_DOOR_OPEN, 0);
// Close tray
mciSendCommand(mPar.wDeviceID, MCI_SET, MCI_SET_DOOR_CLOSED, 0);
// Close device
mciSendCommand(mPar.wDeviceID, MCI_CLOSE, MCI_WAIT, 0);
return 0;
}
Try using DevC++ IDE (WINDOWS ONLY)
Then follow steps:
Step 1:
File > Project > Console Application << Enter
Step 2:
Project Options > Parameters > Linker > write "-lWinmm" in Linker << Enter
Step 3: Open cdtray Copy and paste this small code in your IDE. I recommend DevC++ for this one..
#include<windows.h>
int main(){
mciSendString("set cdaudio door open",0,0,0);
}
Step 4: Close tray, Just change door 'open' to 'closed'
mciSendString("set cdaudio door closed",0,0,0);

Problem Reading MBR with DeviceIoControl function

I get error while calling DeviceIoControl Function to read the MBR of a removable device. The error code is 5. That means access denied! I am using windows xp sp2.
#include "stdafx.h"
#include <windows.h>
#include <winioctl.h>
#include <stdio.h>
BOOL GetMBR(PARTITION_INFORMATION *pdg)
{
HANDLE hDevice; // handle to the drive to be examined
BOOL bResult; // results flag
DWORD junk; // discard results
hDevice = CreateFile(TEXT("\\\\.\\G:"), // drive to open
0, // no access to the drive
FILE_SHARE_READ | // share mode
FILE_SHARE_WRITE,
NULL, // default security attributes
OPEN_EXISTING, // disposition
0, // file attributes
NULL // do not copy file attributes
);
if (hDevice == INVALID_HANDLE_VALUE) // cannot open the drive
{
printf("CreateFile() failed!\n");
return (FALSE);
}
bResult = DeviceIoControl(
hDevice, // device to be queried
IOCTL_DISK_GET_PARTITION_INFO, // operation to perform
NULL, 0, // no input buffer
pdg, sizeof(*pdg), // output buffer
&junk, // # bytes returned
(LPOVERLAPPED) NULL // synchronous I/O
);
CloseHandle(hDevice);
return (bResult);
}
int _tmain(int argc, _TCHAR* argv[])
{
PARTITION_INFORMATION pdg; // disk drive geometry structure
BOOL bResult; // generic results flag
ULONGLONG DiskSize; // size of the drive, in bytes
bResult = GetMBR(&pdg);
if (bResult)
{
}
else
{
printf ("GetDriveGeometry() failed. Error %ld.\n", GetLastError ());
}
getchar();
return ((int)bResult);
}
Open it with FILE_READ_ATTRIBUTES.