/*
* Shortcut.CPP
* 15 Jan 97 by Aldo Calpini <dada@perl.it>
*
* XS interface to the Win32 IShellLink Interface
* based on Registry.CPP written by Jesse Dougherty
*
* Version: 0.03 07 Apr 97
*
*/
#define WIN32_LEAN_AND_MEAN
#include <stdlib.h>
#include <math.h>
#include <windows.h>
#include <shlobj.h>
#include <shlguid.h>
#include <objbase.h>
#if defined(__cplusplus)
extern "C" {
#endif
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#if defined(__cplusplus)
}
#endif
#ifndef _WIN64
# define DWORD_PTR DWORD
#endif
// Section for the constant definitions.
#define CROAK croak
#define MAX_LENGTH 2048
#define TMPBUFSZ 1024
DWORD
constant(char *name, int arg)
{
errno = 0;
switch (*name) {
case 'A':
break;
case 'B':
break;
case 'C':
break;
case 'D':
break;
case 'E':
break;
case 'F':
break;
case 'G':
break;
case 'H':
break;
case 'I':
break;
case 'J':
break;
case 'K':
break;
case 'L':
break;
case 'M':
break;
case 'N':
break;
case 'O':
break;
case 'P':
break;
case 'Q':
break;
case 'R':
break;
case 'S':
if (strncmp(name, "SLGP_", 5) == 0)
switch(name[5]) {
case 'S':
if (strEQ(name, "SLGP_SHORTPATH"))
#ifdef SLGP_SHORTPATH
return SLGP_SHORTPATH;
#else
goto not_there;
#endif
break;
case 'U':
if (strEQ(name, "SLGP_UNCPRIORITY"))
#ifdef SLGP_UNCPRIORITY
return SLGP_UNCPRIORITY;
#else
goto not_there;
#endif
break;
}
if (strncmp(name, "SW_", 3) == 0)
switch(name[3]) {
case 'H':
if (strEQ(name, "SW_HIDE"))
#ifdef SW_HIDE
return SW_HIDE;
#else
goto not_there;
#endif
break;
case 'M':
if (strEQ(name, "SW_MINIMIZE"))
#ifdef SW_MINIMIZE
return SW_MINIMIZE;
#else
goto not_there;
#endif
break;
case 'R':
if (strEQ(name, "SW_RESTORE"))
#ifdef SW_RESTORE
return SW_RESTORE;
#else
goto not_there;
#endif
break;
case 'S':
if (strEQ(name, "SW_SHOW"))
#ifdef SW_SHOW
return SW_SHOW;
#else
goto not_there;
#endif
if (strEQ(name, "SW_SHOWMAXIMIZED"))
#ifdef SW_SHOWMAXIMIZED
return SW_SHOWMAXIMIZED;
#else
goto not_there;
#endif
if (strEQ(name, "SW_SHOWMINIMIZED"))
#ifdef SW_SHOWMINIMIZED
return SW_SHOWMINIMIZED;
#else
goto not_there;
#endif
if (strEQ(name, "SW_SHOWMINNOACTIVE"))
#ifdef SW_SHOWMINNOACTIVE
return SW_SHOWMINNOACTIVE;
#else
goto not_there;
#endif
if (strEQ(name, "SW_SHOWNA"))
#ifdef SW_SHOWNA
return SW_SHOWNA;
#else
goto not_there;
#endif
if (strEQ(name, "SW_SHOWNOACTIVE"))
#ifdef SW_SHOWNOACTIVE
return SW_SHOWNOACTIVE;
#else
goto not_there;
#endif
if (strEQ(name, "SW_SHOWNORMAL"))
#ifdef SW_SHOWNORMAL
return SW_SHOWNORMAL;
#else
goto not_there;
#endif
break;
}
break;
case 'T':
break;
case 'U':
break;
case 'V':
break;
case 'W':
break;
case 'X':
break;
case 'Y':
break;
case 'Z':
break;
}
errno = EINVAL;
return 0;
not_there:
errno = ENOENT;
return 0;
}
MODULE = Win32::Shortcut PACKAGE = Win32::Shortcut
PROTOTYPES: DISABLE
BOOT:
CoInitialize(NULL);
long
constant(name,arg)
char *name
int arg
CODE:
RETVAL = constant(name, arg);
OUTPUT:
RETVAL
void
_Instance(...)
PPCODE:
HRESULT hres;
IShellLink* ilink;
hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
IID_IShellLink, (void **) &ilink);
EXTEND(SP,2);
if (SUCCEEDED(hres)) {
IPersistFile* ifile;
hres = ilink->QueryInterface(IID_IPersistFile, (void **) &ifile);
if (SUCCEEDED(hres)) {
ST(0)=sv_2mortal(newSViv((DWORD_PTR) ilink));
ST(1)=sv_2mortal(newSViv((DWORD_PTR) ifile));
XSRETURN(2);
}
XSRETURN_NO;
}
XSRETURN_NO;
void
_Release(ilink,ifile)
IShellLink * ilink
IPersistFile * ifile
PPCODE:
ifile->Release();
ilink->Release();
XSRETURN_YES;
void
_SetDescription(ilink,ifile,description)
IShellLink * ilink
IPersistFile * ifile
LPCSTR description
PPCODE:
HRESULT hres;
hres = ilink->SetDescription(description);
if (SUCCEEDED(hres))
XSRETURN_YES;
else
XSRETURN_NO;
void
_GetDescription(ilink,ifile)
IShellLink * ilink
IPersistFile * ifile
PPCODE:
HRESULT hres;
char description[1024];
hres = ilink->GetDescription(description, 1024);
if (SUCCEEDED(hres))
XSRETURN_PV(description);
else
XSRETURN_NO;
void
_SetPath(ilink,ifile,path)
IShellLink * ilink
IPersistFile * ifile
LPCSTR path
PPCODE:
HRESULT hres;
hres = ilink->SetPath(path);
if (SUCCEEDED(hres))
XSRETURN_YES;
else
XSRETURN_NO;
void
_GetPath(ilink,ifile,flags)
IShellLink * ilink
IPersistFile * ifile
DWORD flags
PPCODE:
HRESULT hres;
char path[MAX_PATH];
WIN32_FIND_DATA file;
hres = ilink->GetPath((LPSTR) path, MAX_PATH, &file, flags);
if (SUCCEEDED(hres))
XSRETURN_PV(path);
else
XSRETURN_NO;
void
_SetArguments(ilink,ifile,arguments)
IShellLink * ilink
IPersistFile * ifile
LPCSTR arguments
PPCODE:
HRESULT hres;
hres=ilink->SetArguments(arguments);
if (SUCCEEDED(hres))
XSRETURN_YES;
else
XSRETURN_NO;
void
_GetArguments(ilink,ifile)
IShellLink * ilink
IPersistFile * ifile
PPCODE:
HRESULT hres;
char arguments[1024];
hres = ilink->GetArguments((LPSTR) arguments, 1024);
if (SUCCEEDED(hres))
XSRETURN_PV(arguments);
else
XSRETURN_NO;
void
_SetWorkingDirectory(ilink,ifile,dir)
IShellLink * ilink
IPersistFile * ifile
LPCSTR dir
PPCODE:
HRESULT hres;
hres = ilink->SetWorkingDirectory(dir);
if (SUCCEEDED(hres))
XSRETURN_YES;
else
XSRETURN_NO;
void
_GetWorkingDirectory(ilink,ifile)
IShellLink * ilink
IPersistFile * ifile
PPCODE:
HRESULT hres;
char dir[MAX_PATH];
hres = ilink->GetWorkingDirectory((LPSTR) dir, MAX_PATH);
if (SUCCEEDED(hres))
XSRETURN_PV(dir);
else
XSRETURN_NO;
void
_SetShowCmd(ilink,ifile,flag)
IShellLink * ilink
IPersistFile * ifile
int flag
PPCODE:
HRESULT hres;
hres = ilink->SetShowCmd(flag);
if (SUCCEEDED(hres))
XSRETURN_YES;
else
XSRETURN_NO;
void
_GetShowCmd(ilink,ifile)
IShellLink * ilink
IPersistFile * ifile
PPCODE:
HRESULT hres;
int show;
hres = ilink->GetShowCmd(&show);
if (SUCCEEDED(hres))
XSRETURN_IV(show);
else
XSRETURN_NO;
void
_SetHotkey(ilink,ifile,hotkey)
IShellLink * ilink
IPersistFile * ifile
unsigned short hotkey
PPCODE:
HRESULT hres;
hres = ilink->SetHotkey(hotkey);
if (SUCCEEDED(hres))
XSRETURN_YES;
else
XSRETURN_NO;
void
_GetHotkey(ilink,ifile)
IShellLink * ilink
IPersistFile * ifile
PPCODE:
HRESULT hres;
unsigned short hotkey;
hres = ilink->GetHotkey(&hotkey);
if (SUCCEEDED(hres))
XSRETURN_IV(hotkey);
else
XSRETURN_NO;
void
_SetIconLocation(ilink,ifile,location,number)
IShellLink * ilink
IPersistFile * ifile
char * location
int number
PPCODE:
HRESULT hres;
hres=ilink->SetIconLocation(location,number);
if (SUCCEEDED(hres))
XSRETURN_YES;
else
XSRETURN_NO;
void
_GetIconLocation(ilink,ifile)
IShellLink * ilink
IPersistFile * ifile
PPCODE:
HRESULT hres;
int number;
char location[MAX_PATH];
hres = ilink->GetIconLocation((LPSTR)location, MAX_PATH, &number);
if (SUCCEEDED(hres)) {
// [dada] does actually returns nothing?
// printf("_GetIconLocation: location=\"%s\",%d\n",location,number);
XST_mPV(0,location);
XST_mIV(1,number);
XSRETURN(2);
}
else {
XSRETURN_NO;
}
void
_Resolve(ilink,ifile,flags)
IShellLink * ilink
IPersistFile * ifile
long flags
PPCODE:
HRESULT hres;
// [dada] hwnd=NULL, not sure about it...
hres = ilink->Resolve(NULL, flags);
if (SUCCEEDED(hres)) {
char path[MAX_PATH];
WIN32_FIND_DATA file;
hres = ilink->GetPath((LPSTR)path, MAX_PATH, &file, 0);
if (SUCCEEDED(hres))
XSRETURN_PV(path);
else
XSRETURN_NO;
}
else
XSRETURN_NO;
void
_Save(ilink,ifile,filename)
IShellLink * ilink
IPersistFile * ifile
LPSTR filename
PPCODE:
HRESULT hres;
unsigned short wfilename[MAX_PATH];
MultiByteToWideChar(CP_ACP, 0, filename, -1, (wchar_t *)wfilename, MAX_PATH);
hres = ifile->Save((wchar_t *)wfilename, TRUE);
if (SUCCEEDED(hres))
XSRETURN_YES;
else
XSRETURN_NO;
void
_Load(ilink,ifile,filename)
IShellLink * ilink
IPersistFile * ifile
LPSTR filename
PPCODE:
HRESULT hres;
unsigned short wfilename[MAX_PATH];
MultiByteToWideChar(CP_ACP, 0, filename, -1, (wchar_t *)wfilename, MAX_PATH);
hres = ifile->Load((wchar_t *)wfilename, STGM_READ);
if (SUCCEEDED(hres))
XSRETURN_YES;
else
XSRETURN_NO;
void
_Exit(...)
PPCODE:
CoUninitialize();
XSRETURN_YES;