SetValue and Release are not functions
Asked Answered
N

1

1

In summary: I searched MSDN and thought to create my own SetValue but I can't find any sourcecode for it. It's not in a DLL, its like InitPropVariantFromString, it's in a header file, but I can't find it. :( If you can please just show me htat C++ code I'll take it from there :)

Bottom stuff is to show the efforts I put on it.


This is the tiny C++ code I'm converting:

OnCreate(HWND hwnd, LPCREATESTRUCT lpcs)
{
 IPropertyStore *pps;
 HRESULT hr = SHGetPropertyStoreForWindow(hwnd, IID_PPV_ARGS(&pps));
 if (SUCCEEDED(hr)) {
  IPropertyStore_SetValue(pps, PKEY_AppUserModel_ID, L"Contoso.Scratch");
 }
}

I have translated this to:

  var ppv = ctypes.voidptr_t(0);
  var pps = new IID();
  var HR_pps = CLSIDFromString('{886D8EEB-8CF2-4446-8D02-CDBA1DBDCF99}', pps.address());
  if (!checkHRESULT(HR_pps)) { throw new Error('checkHRESULT error'); }

  var hr = SHGetPropertyStoreForWindow(hwnd, pps.address(), ppv.address());
  if (!checkHRESULT(hr)) { throw new Error('checkHRESULT error'); }

  var pszValue = ctypes.jschar.array()('Contoso.Scratch'); // PCWSTR
  IPropertyStore_SetValue(pps.address(), PKEY_AppUserModel_ID, pszValue.address());

This IPropertyStore_SetValue I converted from this C++:

HRESULT IPropertyStore_SetValue(IPropertyStore *pps, REFPROPERTYKEY pkey, PCWSTR pszValue)
{
 PROPVARIANT var;
 HRESULT hr = InitPropVariantFromString(pszValue, &var);
 if (SUCCEEDED(hr)) {
  hr = pps->SetValue(pkey, var);
  PropVariantClear(&var);
 }
 return hr;
}

I got it to:

var struct_PROPVARIANT = ctypes.StructType('PROPVARIANT', [
  {'fntud': struct_GUID}, // GUID
  {'pid': ctypes.unsigned_long}, // DWORD
  // comment from loomo on union :: union not supported by js-ctypes https://bugzilla.mozilla.org/show_bug.cgi?id=535378 "You can always typecast pointers, at least as long as you know which type is the biggest"
  // so now in my case i know that InitPropVariantFromString is looking to se the pwszVal so forget all the other crap in the union and just leave this one
  {'pwszVal': new ctypes.PointerType(ctypes.jschar)}  // LPWSTR 
]);

var IPropertyStore_SetValue = function(pps /** IPopertyStore pointer **/, pkey /** PROPERTYKEY **/, pszValue /** PCWSTR **/) {
  var v = new struct_PROPVARIANT(); // PROPVARIANT

  var rez = InitPropVariantFromString(pszValue, v.address());
  if (rez) {
    console.info('pps.SetValue', pps.SetValue);
    pps.SetValue(pkey, v);
  } else {
    throw new Error('failed InitPropVariantFromString');
  }
  return true;
}

So this required me to write InitPropVariantFromString which I did:

function InitPropVariantFromString(string /** PCWSTR **/, propvarPtr /** PROPVARIANT pointer **/) {
    var hr = SHStrDup(string, propvarPtr.contents.pwszVal.address());
    if (!checkHRESULT(hr)) {
       //PropVariantInit(propvarPtr); //can skip this, it just does a memset
    }
    return true;                      
}

A SMALL ASIDE ON MY SHSTRDUP DILEMMA (not a question just showing i worked hard and through unexplainable weirdness got it to work)

So this required me to do SHStrDup which I thought would take two arguments of ctypes.jschar.ptr as it is first argument of LPCTSTR and second arg of LPTSTR.

For the first argument, i was passing the PCWSTR of recall ctypes.jschar.array()('Contoso.Scratch'). So when I the first arg definition set to ctypes.jschar.ptr it wouldn't work use it throws this error: expected type pointer, got ctypes.jschar.array(16).ptr(ctypes.UInt64("0x2855b560"))

So I change in the defintion from ctypes.jschar.ptr to ctypes.voidptr_t in defintion so then it worked for this argument but then threw error on second argument recall the propvarPtr.contents.pwszVal.address():

ctypes.jschar.ptr.ptr(ctypes.UInt64("0x20fdb3b4")),

So then I just ended up setting both arguments of SHStrDup to ctypes.voidptr_t and it worked. Don't know why but it worked. And propvarPtr.contents.pwszVal is definitely getting populated, because when I console.log it it shows: "propvarPtr.contents.pwszVal" CData { contents: "C" }.

So the final SHStrDup defintion looked like this:

/* http://msdn.microsoft.com/en-us/library/windows/desktop/bb759924%28v=vs.85%29.aspx
* HRESULT SHStrDup(
*   __in_   LPCTSTR pszSource,
*   __out_  LPTSTR *ppwsz
* );
*/
var SHStrDup = shlwapi.declare('SHStrDupW', ctypes.winapi_abi, ctypes.long, // HRESULT
  ctypes.voidptr_t, // LPCTSTR // should be ctypes.jschar.ptr OR ctypes.char.ptr // im trying to pass PCWSTR here, which is `ctypes.jschar.array()('blah blah').address()`
  ctypes.voidptr_t // LPTSTR // should be ctypes.jschar.ptr OR ctypes.char.ptr // im trying to pass address to struct_PROPVARIANT.pwszVal which is new ctypes.PointerType(ctypes.jschar)
);

So now all that is passing and I end up back in IPropertyStore_SetValue in this if:

  var rez = InitPropVariantFromString(pszValue, v.address());
  if (rez) {
    console.info('pps.SetValue', pps.SetValue);
    pps.SetValue(pkey, v);
  } else {
    throw new Error('failed InitPropVariantFromString');
  }

Now rez is true, so then it now tries pps.SetValue and this is where it goes kaput and I can't figure out how to fix it. :(

I searched MSDN and thought to create my own SetValue but I can't find any sourcecode for it. It's not in a DLL, its like InitPropVariantFromString, it's in a header file, but I can't find it. :( If you can please just show me htat C++ code I'll take it from there :)

Niello answered 4/7, 2014 at 19:6 Comment(4)
IIRC you don't have any knowledge of C++, and if you had you would realize how futile is what you 're trying to do, but in any case here is the definition of IPropertyStore_SetValueParasitize
Thanks so much man! I'll figure it out man or I'll find some other way! Can you please make this the solution. I want to vote it up because I spent a long time looking and couldnt find it I really appreciate it. I made a friend from Cisco I'm going to try to invite him over make him some tea and salad cookies and hopefully he'll sit down with me. He sat down with me when i was massively stuck on remote allocation. haha but I need to get everything togather so we can just sit down for a few hours. otherwise ill flounder around with him here haha. thanks so much man. plz move to solution.Niello
Also worst case scenario i cant do it then at least we got a bunch of new stuff to share as examples it can probably help someone somewhere. Maybe i can request new features to ctypes :P im hopeful man! :PNiello
@Parasitize see solution, pastebin, copy paste to scratchpad! run that! :D ya god!!! i used your link to get the order of the defintions in the Vtbl so your help of posting that link really helped!! :)Niello
N
0

Solved, I had to use VTBL: https://github.com/Noitidart/_scratchpad/blob/master/IPropertyStore%20COM%20jsctypes.js

The order of the defintions in the Vtbl matter big time. So make sure its correct if you want to do something with Vtbls

var IPropertyStoreVtbl = new ctypes.StructType('IPropertyStoreVtbl');
var IPropertyStore = new ctypes.StructType('IPropertyStore', [{
    'lpVtbl': IPropertyStoreVtbl.ptr
}]);
this.IPropertyStorePtr = new ctypes.PointerType(IPropertyStore);

IPropertyStoreVtbl.define(
    [{ //start inherit from IUnknown
        'QueryInterface': ctypes.FunctionType(ctypes.stdcall_abi,
            this.HRESULT, [
                IPropertyStore.ptr,
                this.REFIID,    // riid
                this.VOIDPTR    // **ppvObject
            ]).ptr
    }, {
        'AddRef': ctypes.FunctionType(ctypes.stdcall_abi,
            this.ULONG, [
                IPropertyStore.ptr
            ]).ptr
    }, {
        'Release': ctypes.FunctionType(ctypes.stdcall_abi,
            this.ULONG, [
                IPropertyStore.ptr
            ]).ptr
    }, { //end inherit from IUnknown //start IPropertyStore
        'GetCount': ctypes.FunctionType(ctypes.stdcall_abi,
            this.HRESULT, [
                IPropertyStore.ptr,
                this.DWORD.ptr  // *cProps
            ]).ptr
    }, {
        'GetAt': ctypes.FunctionType(ctypes.stdcall_abi,
            this.HRESULT, [
                IPropertyStore.ptr,
                this.DWORD,             // iProp
                this.PROPERTYKEY.ptr    //*pkey
            ]).ptr
    }, {
        'GetValue': ctypes.FunctionType(ctypes.stdcall_abi,
            this.HRESULT, [
                IPropertyStore.ptr,
                this.REFPROPERTYKEY,    // key
                this.PROPVARIANT.ptr    // *pv
            ]).ptr
    }, {
        'SetValue': ctypes.FunctionType(ctypes.stdcall_abi,
            this.HRESULT, [
                IPropertyStore.ptr,
                this.REFPROPERTYKEY,    // key
                this.REFPROPVARIANT     // propvar
            ]).ptr
    }, {
        'Commit': ctypes.FunctionType(ctypes.stdcall_abi,
            this.HRESULT, [
                IPropertyStore.ptr
            ]).ptr
    }]
);

Then to get the IPropertyStore of a window:

var ppsPtr = new ostypes.IPropertyStorePtr();
var hr_SHGetPropertyStoreForWindow = _dec('SHGetPropertyStoreForWindow')(cHwnd, IID_IPropertyStore.address(), ppsPtr.address()); 
checkHRESULT(hr_SHGetPropertyStoreForWindow, 'SHGetPropertyStoreForWindow');
var pps = ppsPtr.contents.lpVtbl.contents;

now you can use IPropertyStore :: SetValue and IPropertyStore :: Release but make sure to pass the ppsPtr as first argument to them then the remaining arguments are what you would expect: var hr = pps.SetValue(ppsPtr, firstArgOf_SetValue, secondArgOf_SetValue)


EDIT:

adding copy paste runnable script from scratchpad. Copy and paste this: http://pastebin.mozilla.org/8429999

this will do the equivalent of this XPCOM:

 var win = Services.wm.getMostRecentWindow(null);
 Cc["@mozilla.org/windows-taskbar;1"].getService(Ci.nsIWinTaskbar).setGroupIdForWindow(win, 'Contoso.Scratch')

Yes its long but the good thing about it is, there is no XPCOM to set RelaunchCommand and RelaunchIconResource etc. Thats why js-ctypes is needed.

Niello answered 11/1, 2015 at 21:19 Comment(3)
harhar, writing C++ vtable ptrs in C in js-ctypes. nice.Satanism
@Satanism :D :D :D i jacked the methodology from here: github.com/west-mt/ssbrowser/blob/… :D :DNiello
hey @Satanism i edited the topic, below the hr line i added a snippet of the XPCOM, and then a copy paste snippet of the js-ctypes, you can run it and youll see the scratchpad window get ungrouped from the current group. :) I also fixed the vtbl defintions order, as that matters hugelyNiello

© 2022 - 2024 — McMap. All rights reserved.