Access violation reading location in C Direct Show - c

I keep getting an access violation reading location error in Visual Studio when I execute the code. I also am unable to print the address for troubleshooting. I have no idea what is going on and according to a friend, my code is flawless and that it is a hardware issue. The file seems to be alright so idk if my friend is trolling me or not. My code is here:
#include <dshow.h>
#include <stdio.h>
#include <Windows.h>
void main(void)
{
while (TRUE)
{
char SongName[10];
printf("Song name:\n");
scanf_s("%s", &SongName,10);
HRESULT hr = CoInitialize(NULL);
IGraphBuilder* pGraph = NULL;
hr = CoCreateInstance(&CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER, &IID_IGraphBuilder, (void**)&pGraph);
IMediaControl* pControl = NULL;
IMediaEvent* pEvent = NULL;
hr = pGraph->lpVtbl->QueryInterface(pGraph, &IID_IMediaControl, (void**)&pControl);
hr = pGraph->lpVtbl->QueryInterface(pGraph, &IID_IMediaEvent, (void**)&pEvent);
char SongAddress = (L"C:/Users/Desktop/AudioPlayer/%s",SongName);
wprintf("%s", SongAddress);
hr = pGraph->lpVtbl->RenderFile(pGraph,SongAddress, NULL);
hr = pControl->lpVtbl->Run(pControl);
FILTER_STATE fs;
hr = pControl->lpVtbl->GetState(pControl,10000, (OAFilterState*)&fs);
if (fs != NULL) {
printf("%d", fs);
}
long evCode = 0;
pEvent->lpVtbl->WaitForCompletion(pEvent, INFINITE, &evCode);
pControl->lpVtbl->Release(pControl);
pEvent->lpVtbl->Release(pEvent);
pGraph->lpVtbl->Release(pGraph);
CoUninitialize();
}
}
Error shows in this line:
hr = pGraph->lpVtbl->RenderFile(pGraph,SongAddress, NULL);

Related

How to call EnumAdapters from IDXGFactory in c?

How to call the EnumAdapters function in c from IDXGFactory
UINT i = 0;
IDXGIFactory* pFactory = NULL;
IDXGIAdapter * pAdapter;
HRESULT hr = CreateDXGIFactory(&IID_IDXGIFactory, (void**)(&pFactory) );
if (hr != S_OK)
{
printf("Failed to create DXIFactory object\n");
}
using pFactory->EnumAdapters(i, pAdapter) does not work and causes this error
struct "IDXGIFactory" has no field "EnumAdapters"
You are interested in reading up on topic "using COM in plain C", where you can find relevant detailed explanations.
For you very specific question the code might look like:
#include <dxgi.h>
#pragma comment(lib, "dxgi.lib")
#pragma comment(lib, "dxguid.lib")
int main()
{
IDXGIFactory* pFactory = NULL;
UINT i = 0;
IDXGIAdapter* pAdapter;
HRESULT hr;
hr = CreateDXGIFactory(&IID_IDXGIFactory, (void**)(&pFactory));
hr = pFactory->lpVtbl->EnumAdapters(pFactory, i, &pAdapter);
return 0;
}
Or, another way is to take advantage of COBJMACROS in which case you have IDXGIFactory_EnumAdapters available to you.
#define COBJMACROS
#include <dxgi.h>
#pragma comment(lib, "dxgi.lib")
#pragma comment(lib, "dxguid.lib")
int main()
{
IDXGIFactory* pFactory = NULL;
UINT i = 0;
IDXGIAdapter* pAdapter;
HRESULT hr;
hr = CreateDXGIFactory(&IID_IDXGIFactory, (void**)(&pFactory));
hr = IDXGIFactory_EnumAdapters(pFactory, i, &pAdapter);
return 0;
}

XCB EWMH getting client list returns only Google Chrome windows

I am using XCB to write my own window manager. To create a taskbar I need to get list of all the windows. I could track them and keep it somewhere, but I can see on the github that many other solutions are using EWMH to do this.
However, no matter what are the circumstances, my code has only the Google Chrome windows. I am using Arch linus with Gnome 41. When using Xephyr, no windows are returned at all.
#include "tasks.h"
#include "log.h"
#include <stdio.h>
#include <stdlib.h>
#include <xcb/xcb.h>
#include <xcb/xcb_ewmh.h>
#include <xcb/xcb_icccm.h>
#include <xcb/xproto.h>
Task *tasks_get_all(xcb_connection_t *conn, xcb_ewmh_connection_t *ewmh,
int screen_number) {
xcb_get_property_reply_t *reply;
xcb_get_property_cookie_t cookie;
xcb_window_t *windows;
cookie = xcb_ewmh_get_client_list(ewmh, screen_number);
xcb_ewmh_get_windows_reply_t winlist;
if (!xcb_ewmh_get_client_list_reply(ewmh, cookie, &winlist, NULL)) {
log_error("Cannot get windows list");
return NULL;
}
Task *prev_task = NULL;
Task *tasks = NULL;
xcb_ewmh_get_utf8_strings_reply_t ewmh_txt_prop;
for (int i = 0; i < winlist.windows_len; i++) {
Task *task = malloc(sizeof(Task));
task->next = NULL;
task->name = "";
cookie = xcb_ewmh_get_wm_visible_name_unchecked(ewmh, winlist.windows[i]);
xcb_ewmh_get_wm_name_reply(ewmh,
xcb_ewmh_get_wm_name(ewmh, winlist.windows[i]),
&ewmh_txt_prop, NULL);
task->name = ewmh_txt_prop.strings;
ewmh_txt_prop.strings = NULL;
if (tasks == NULL) {
tasks = task;
}
if (prev_task != NULL) {
prev_task->next = task;
}
prev_task = task;
}
xcb_ewmh_get_windows_reply_wipe(&winlist);
return tasks;
}

PrintDlgEx fails with "Invalid Argument"

I am Working with Win32 API and C.
I need to get supported page sizes of my system default printer.
Referring to DeviceCapabilities of a network printer on this forum (which suggested PrintDlg), I am trying to use PrintDlgEx, with Flags=PD_RETURNDEFAULT.
My problem is, call to PrintDlgEx fails with error "E_INVALIDARG", ie, Invalid Argument.
I have written the code as a console program.
Can some one help me identify what is going wrong.
My code is pasted below
int main(void)
{
HWND Myhwnd = GetConsoleWindow();
if (Myhwnd == NULL)
printf("GetConsoleWindow Failed \n");
PRINTDLGEX pdlg;
memset(&pdlg, 0, sizeof(PRINTDLGEX));
pdlg.lStructSize = sizeof(PRINTDLGEX);
pdlg.hwndOwner = Myhwnd;
pdlg.Flags = PD_RETURNDEFAULT|| PD_NOPAGENUMS;
pdlg.nCopies = 1;
pdlg.nPropertyPages = 0;
pdlg.dwResultAction = 0;
pdlg.nStartPage = START_PAGE_GENERAL;
HRESULT result = PrintDlgEx(&pdlg);
switch (result)
{
... ...
case E_INVALIDARG:
printf("Invalid Argument\n");
break;
}
return 0;
}
I noticed in PrintDlgEx documentation it says "This structure must be declared dynamically using a memory allocation function.". So I changed my program as below, but still gives same error "Invalid Argument".
int main(void)
{
HWND Myhwnd = GetConsoleWindow();
if (Myhwnd == NULL)
printf("GetConsoleWindow Failed \n");
PRINTDLGEX * pdlg;
pdlg = malloc(sizeof(PRINTDLGEX));
memset(pdlg, 0, sizeof(PRINTDLGEX));
pdlg->lStructSize = sizeof(PRINTDLGEX);
pdlg->hwndOwner = Myhwnd;
pdlg->Flags = PD_RETURNDEFAULT|| PD_NOPAGENUMS;
pdlg->nCopies = 1;
pdlg->nPropertyPages = 0;
pdlg->dwResultAction = 0;
pdlg->nStartPage = START_PAGE_GENERAL;
HRESULT result = PrintDlgEx(pdlg);
switch (result)
{
... ...
case E_INVALIDARG:
printf("Invalid Argument\n");
break;
}
return 0;
}
I have checked your code with MSVC2019. As IInspectable said in a comment, the error is the use of boolean or || operator instead of bitwise or |operator.
I also checked that the call work with a statically allocated PRINTDLGEX variable or a dynamically allocated one.
The code is:
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
int main(void)
{
HWND Myhwnd = GetConsoleWindow();
if (Myhwnd == NULL)
printf("GetConsoleWindow Failed \n");
PRINTDLGEX pdlg;
memset(&pdlg, 0, sizeof(PRINTDLGEX));
pdlg.lStructSize = sizeof(PRINTDLGEX);
pdlg.hwndOwner = Myhwnd;
pdlg.Flags = PD_RETURNDEFAULT | PD_NOPAGENUMS;
pdlg.nCopies = 1;
pdlg.nPropertyPages = 0;
pdlg.dwResultAction = 0;
pdlg.nStartPage = START_PAGE_GENERAL;
HRESULT result = PrintDlgEx(&pdlg);
switch (result)
{
case S_OK:
printf("Success\n");
break;
case E_INVALIDARG:
printf("Invalid Argument\n");
break;
default:
printf("Error %d\n", result);
break;
}
return 0;
}

CreateWellKnownSid says Parameter is incorrect with WinAccountAdministratorSid, but works with WinBuiltAdministratorsSid

I am trying to get the well known SID for the builtin administrator account using CreateWellKnownSid so I can use it in other functions, but I am getting The parameter is incorrect error message when using WinAccountAdministratorSid as first parameter; however, if I use WinBuiltinAdministratorsSid or WinBuiltinUsersSid it works. No idea what's going on.
Code:
#include <Windows.h>
#include <wchar.h>
#include <LM.h>
#include <locale.h>
#pragma comment(lib, "Netapi32.lib")
#define MAX_NAME 256
VOID ShowError(DWORD errorCode)
{
//FormatMessageW
DWORD flags = FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS;
LPWSTR errorMessage;
DWORD size = 0;
if (!FormatMessageW(flags, NULL, errorCode, 0, (LPWSTR)&errorMessage, size, NULL))
{
fwprintf(stderr, L"Could not get the format message, error code: %u\n", GetLastError());
exit(1);
}
wprintf(L"\n%s", errorMessage);
LocalFree(errorMessage);
}
int wmain(int argc, WCHAR **argv)
{
_wsetlocale(LC_ALL, L"English");
//LocalAlloc
UINT memFlags = LMEM_FIXED; //Allocates fixed memory
DWORD numOfBytes = SECURITY_MAX_SID_SIZE;
PSID builtInAdminSid;
/*Allocating memory to hold the SID for the
built-in administrator user*/
if (!(builtInAdminSid = LocalAlloc(memFlags, numOfBytes)))
{
ShowError(GetLastError());
return 1;
}
//CreateWellKnownSid
WELL_KNOWN_SID_TYPE accountAdminSid = WinAccountAdministratorSid;
PSID domainSid = NULL;
/*We will ask Windows for the well known Admin SID.
If this function fails, we cannot continue*/
if (!CreateWellKnownSid(accountAdminSid, NULL,
builtInAdminSid, &numOfBytes))
{
ShowError(GetLastError());
LocalFree(builtInAdminSid); //Do not forget to free memory!
return 1;
}
return 0;
}
Am I doing something wrong?
EDIT:
Seems like I have to specify the DomainSid parameter, but how do I retrieve it for the local computer?
some time CreateWellKnownSid require DomainSid parameter by very simply reason - it concatenation the DomainSid with well known rid (add one SubAuthority to sid).
for get DomainSid we can use LsaQueryInformationPolicy with PolicyAccountDomainInformation - Retrieves the name and SID of the system's account domain. - this api call return POLICY_ACCOUNT_DOMAIN_INFO structure where exist DomainSid
#include <Ntsecapi.h>
ULONG CreateSid()
{
LSA_HANDLE PolicyHandle;
static LSA_OBJECT_ATTRIBUTES oa = { sizeof(oa) };
NTSTATUS status = LsaOpenPolicy(0, &oa, POLICY_VIEW_LOCAL_INFORMATION, &PolicyHandle);
if (0 <= status)
{
PPOLICY_ACCOUNT_DOMAIN_INFO ppadi;
if (0 <= (status = LsaQueryInformationPolicy(PolicyHandle, PolicyAccountDomainInformation, (void**)&ppadi)))
{
PSID sid = alloca(MAX_SID_SIZE);
ULONG cbSid = MAX_SID_SIZE;
if (!CreateWellKnownSid(::WinAccountAdministratorSid, ppadi->DomainSid, sid, &cbSid))
{
status = GetLastError();
}
LsaFreeMemory(ppadi);
}
LsaClose(PolicyHandle);
}
return status;
}
For those who wonder how I set the RbMm's answer to my code, here it is:
// LsaOpenPolicy
NTSTATUS nOpenPolicy;
LSA_OBJECT_ATTRIBUTES objectAttributes;
LSA_HANDLE policyHandle;
// Fills a block of memory with zeros.
ZeroMemory(&objectAttributes, sizeof(objectAttributes));
nOpenPolicy = LsaOpenPolicy(NULL, &objectAttributes,
POLICY_VIEW_LOCAL_INFORMATION, &policyHandle);
if (nOpenPolicy != STATUS_SUCCESS)
{
ShowError(LsaNtStatusToWinError(nOpenPolicy));
LocalFree(builtInAdminSid);
return 1;
}
// LsaQueryInformationPolicy
NTSTATUS nQueryInfo;
POLICY_INFORMATION_CLASS policyInformation = PolicyAccountDomainInformation;
PPOLICY_ACCOUNT_DOMAIN_INFO pDomainInfo;
nQueryInfo = LsaQueryInformationPolicy(policyHandle, policyInformation, (PVOID *)&pDomainInfo);
if (nQueryInfo != STATUS_SUCCESS)
{
ShowError(LsaNtStatusToWinError(nQueryInfo));
LocalFree(builtInAdminSid);
LsaClose(policyHandle);
return 1;
}
// CreateWellKnownSid
WELL_KNOWN_SID_TYPE accountAdminSid = WinAccountAdministratorSid;
/* We will ask Windows for the well known Admin SID.
If this function fails, we cannot continue */
if (!CreateWellKnownSid(accountAdminSid, pDomainInfo->DomainSid,
builtInAdminSid, &numOfBytes))
{
ShowError(GetLastError());
LocalFree(builtInAdminSid); // Do not forget to free memory!
LsaClose(policyHandle);
return 1;
}
LsaClose(policyHandle);
LsaFreeMemory(pDomainInfo);

Volume Shadow Copy Service (VSS) sample in C?

I been trying to read the documentation for the API functions of Volume Shadow Copy Service, for the purpose of copying files that are currently locked (being used) under Windows XP.
Unfortunately I don't seem to get nowhere. Anybody happen to have a code sample of how to interact with the API, for copying such files?
Thanks, Doori Bar
I've had similar troubles, after a lot of hit-and-trials I've managed to get somewhere...
here's a code snippet which may help:
#include <stdio.h>
#include <windows.h>
#include <winbase.h>
#include <Vss.h>
#include <VsWriter.h>
#include <VsBackup.h>
int main()
{
int retCode = 0;
int i=0;
HRESULT hr;
IVssEnumObject *pIEnumSnapshots;
IVssBackupComponents *ab;
VSS_OBJECT_PROP Prop;
VSS_SNAPSHOT_PROP& Snap = Prop.Obj.Snap;
WCHAR existingFilePath[MAX_PATH] = TEXT("\\temp\\PrinterList.txt");
WCHAR newFileLocation[MAX_PATH] = TEXT("c:\\Users\\PrinterList.txt");
TCHAR existingFileLocation[MAX_PATH];
if (CoInitialize(NULL) != S_OK)
{
printf("CoInitialize failed!\n");
return 1;
}
hr = CreateVssBackupComponents(&ab);
if(hr != S_OK)
{
printf("Failed at CreateVssBackupComponents Stage");
return 1;
}
hr = ab->InitializeForBackup();
if(hr != S_OK)
{
printf("Failed at InitializeForBackup Stage");
return 1;
}
hr = ab->SetContext(VSS_CTX_ALL);
if(hr != S_OK)
{
printf("Failed at SetContext Stage");
return 1;
}
hr = ab->Query(GUID_NULL,VSS_OBJECT_NONE, VSS_OBJECT_SNAPSHOT, &pIEnumSnapshots);
if(hr != S_OK){
printf("Failed at Query Stage");
return 1;
}
// Enumerate all shadow copies.
printf("Recursing through snapshots...\n");
while(true)
{
// Get the next element
ULONG ulFetched;
hr = pIEnumSnapshots->Next( 1, &Prop, &ulFetched );
// We reached the end of list
if (ulFetched == 0)
break;
wprintf(L"Snapshot:%s\n", Snap.m_pwszSnapshotDeviceObject);
/*
At this point you have the Snap object with all the information required for copying the file.
example:
Snap.m_pwszSnapshotDeviceObject is the root for snapshot object
(like \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy1)
Snap.m_pwszOriginalVolumeName is the full unicode name
(like \\?\Volume{1240872a-88de-11df-a94d-806e6f6e6963}\)
for the original root(c: mostly)
So, you can use CopyFile() to do what you want
*/
wcscpy(existingFileLocation, Snap.m_pwszSnapshotDeviceObject);
wcscat(existingFileLocation, existingFilePath);
CopyFile(existingFileLocation, newFileLocation, false);
//false here will enable over-write
}
return retCode;
}
Note: If your target machine is not the same as build machine, you'll need to include proper definitions and build configurations.
Note: You will have to use the annoying wchars everywhere, because these functions use them.

Resources