Add context-sensitive Git History item
[git-cheetah/kirill.git] / ext.c
bloba3e7c9513031e5d936c385a2d5db84b5e654d24e
1 #include <shlobj.h>
2 #include <stdarg.h>
3 #include <tchar.h>
4 #include "menuengine.h"
5 #include "ext.h"
6 #include "debug.h"
7 #include "systeminfo.h"
9 DWORD object_count = 0;
10 DWORD lock_count = 0;
13 * Standard methods for the IUnknown interface:
14 * add_ref, release, query_interface and initialize.
16 * Both of our COM objects contain pointers to the git_data object.
19 inline ULONG STDMETHODCALLTYPE add_ref_git_data(struct git_data *this_)
21 return ++(this_->count);
24 inline ULONG STDMETHODCALLTYPE release_git_data(struct git_data *this_)
26 if (--(this_->count) == 0) {
27 GlobalFree(this_);
28 InterlockedDecrement(&object_count);
29 return 0;
31 return this_->count;
34 inline STDMETHODIMP query_interface_git_data(struct git_data *this_,
35 REFIID iid, LPVOID FAR *pointer)
37 if (IsEqualIID(iid, &IID_git_shell_ext) ||
38 IsEqualIID(iid, &IID_IShellExtInit) ||
39 IsEqualIID(iid, &IID_IUnknown)) {
40 *pointer = &this_->shell_ext;
41 } else if (IsEqualIID(iid, &IID_git_menu) ||
42 IsEqualIID(iid, &IID_IContextMenu)) {
43 *pointer = &this_->menu;
44 } else
45 return E_NOINTERFACE;
47 add_ref_git_data(this_);
48 return NOERROR;
51 inline STDMETHODIMP initialize_git_data(struct git_data *this_,
52 LPCITEMIDLIST folder,
53 LPDATAOBJECT data, HKEY id)
55 FORMATETC format
56 = {CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
57 STGMEDIUM stg = {TYMED_HGLOBAL};
58 HDROP drop;
59 UINT count;
60 HRESULT result = S_OK;
62 /* if we can't find msysPath, don't even try to do anything else */
63 if (!msys_path())
64 return E_NOTIMPL;
66 /* store the folder, if provided */
67 if (folder)
68 SHGetPathFromIDList(folder, this_->name);
70 if (!data)
71 return S_OK;
73 if (FAILED(data->lpVtbl->GetData(data, &format, &stg)))
74 return E_INVALIDARG;
76 drop = (HDROP)GlobalLock(stg.hGlobal);
78 if (!drop)
79 return E_INVALIDARG;
81 count = DragQueryFile(drop, 0xFFFFFFFF, NULL, 0);
83 if (count == 0)
84 result = E_INVALIDARG;
85 else if (!DragQueryFile(drop, 0, this_->name, sizeof(this_->name)))
86 result = E_INVALIDARG;
88 GlobalUnlock(stg.hGlobal);
89 ReleaseStgMedium(&stg);
91 return result;
95 * Define the shell extension.
97 * Its sole purpose is to be able to query_interface() the context menu.
99 DEFINE_STANDARD_METHODS(git_shell_ext)
101 struct git_shell_ext_virtual_table git_shell_ext_virtual_table = {
102 query_interface_git_shell_ext,
103 add_ref_git_shell_ext,
104 release_git_shell_ext,
105 initialize_git_shell_ext