The MASM Forum Archive 2004 to 2012

General Forums => The Campus => Topic started by: oex on January 17, 2010, 10:02:25 AM

Title: You'd think shortcut would be quick
Post by: oex on January 17, 2010, 10:02:25 AM
I've checked around but cant find anything but COM IShellLink to safely create lnk shortcuts.... Is there not an api call? I have never done COM.... Maybe COM is more simple than it looks?
Title: Re: You'd think shortcut would be quick
Post by: Vortex on January 17, 2010, 10:11:54 AM
Donkey's Lib Projects, Files.lib :
Quote
List of functions:
CreateLink, CreateLinkIndirect, CreateDesktopLink, CreateStartmenuLink, CreateSpecialFolderLink, ResolveLinkIndirect, ResolveLink, CheckFileName, RecurseFolder, InitCRC32Table, CRC32, FindNameInPath, GetCL, GetFileExists, ReadFileLines, GetFileInfo, TimeStamp2FileTime, FileTime2DateStamp, GetModulePath, RegisterFileExtension, StripFilename, IsShortcut, IsPEFile

http://www.quickersoft.com/donkey/libs.htm
Title: Re: You'd think shortcut would be quick
Post by: oex on January 17, 2010, 10:20:52 AM
He's a star :wink.... Still looking for a non COM version if there is one
Title: Re: You'd think shortcut would be quick
Post by: donkey on January 17, 2010, 11:03:40 AM
Quote from: oex on January 17, 2010, 10:20:52 AM
He's a star :wink.... Still looking for a non COM version if there is one

There is no non COM version in the API, shortcuts can only be manipulated through the IShellLink interface. You can attempt to write your own file handler but it would be a bit of work, I know I once tried then gave up an went with COM:

http://www.stdlib.com/art6-Shortcut-File-Format-lnk.html

Edgar
Title: Re: You'd think shortcut would be quick
Post by: oex on January 17, 2010, 11:14:37 AM
Hi Edgar,

Yeah I saw that link and considered it then decided windows versions would likely as not break my code with an evil grin....

I've been taking a look at your code, I'm assuming FRAME is PROC and understand that if I call invoke CoInitialize say at the begining of my app then call your code for "CreateLink" reworked to MASM syntax I should be fixed up

I'm moding it now, I like the theory of COM but dont like it in practice (probably because I have never properly been introduced to it).... Maybe this will change my mind should it work :bg
Title: Re: You'd think shortcut would be quick
Post by: donkey on January 17, 2010, 11:32:52 AM
Hi oex,

If you translate it to MASM post it here so others can use it, you can also use the function directly from the lib as it is in a MASM compatible format.
Title: Re: You'd think shortcut would be quick
Post by: oex on January 17, 2010, 11:51:03 AM
Quote from: donkey on January 17, 2010, 11:32:52 AM
If you translate it to MASM post it here so others can use it

Yep for sure.... ugly structure patches atm, first time I've seen GoASM syntax should have it fixed up shortly

je >>A1
je >A1

There is important difference?

struct
db

lol it's all foreign to me :bg
Title: Re: You'd think shortcut would be quick
Post by: oex on January 17, 2010, 12:16:15 PM
It builds at least, off for a 6 mile walk will finish off in a couple hours  :bg
Title: Re: You'd think shortcut would be quick
Post by: Vortex on January 17, 2010, 12:26:13 PM
Another COM based project :

How to create short-cuts (link files)

http://www.codeproject.com/KB/winsdk/makelink.aspx
Title: Re: You'd think shortcut would be quick
Post by: oex on January 17, 2010, 04:46:38 PM
OK guys this version should work ok with masm but I would appreciate a double check off someone I havent translated GoASM to Masm before or coded anything for COM

One thing I did notice was that a website link works but has wrong icon it appears an internet shortcut has extension .url and contents:
[InternetShortcut]
URL=http://www.masm32.com/
Title: Re: You'd think shortcut would be quick
Post by: dedndave on January 17, 2010, 06:04:43 PM
shortcuts to web links (.URL files) are not the same as other shortcuts (.LNK)
they resemble a .INI file
the trick here is to get the icon to match the websites favicon (which may or may not be cached in temporary internet files)

this is a shortcut for google - i renamed it from .URL to .TXT and opened it with notepad

[DEFAULT]
BASEURL=http://www.google.com/
[InternetShortcut]
URL=http://www.google.com/
Modified=E0BFB7BD4033CA0151
IconFile=http://www.google.com/favicon.ico
IconIndex=1

all of the sections and values are not needed to make a working shortcut
this one would also work if renamed to .URL - it would have the icon of whatever your default browser is

[InternetShortcut]
URL=http://www.google.com/
Title: Re: You'd think shortcut would be quick
Post by: oex on January 17, 2010, 06:17:42 PM
Awesome thanks for that Dave I had done the same with a Secondlife .url file but they only had the details I posted
Title: Re: You'd think shortcut would be quick
Post by: dedndave on January 17, 2010, 06:23:37 PM
more favicon info....

websites are supposed to use an ICO file named "favicon.ico", place it in the web_root folder, and create an HTML reference tag
those are the MS rules for IE ver 6 favorites

many websites don't follow the rules, and thus may not properly display a favicon when bookmarked with IE 6

some websites use a different name, file type (animated GIFs, for example), or location
the only way to get the right icon for those sites is to open and parse the homepage HTML file

otherwise, you will see the icon from the default browser

here is an example of a site that didn't follow the old rules...
http://www.sesp.cse.clrc.ac.uk/html/SoftwareTools/vtune/users_guide/mergedProjects/analyzer_ec/mergedProjects/reference_olh/reference_olh.htm

the favicon shows up fine using Firefox   :bg
Title: Re: You'd think shortcut would be quick
Post by: oex on January 17, 2010, 07:01:21 PM
Oh joy! They Changed It!

In 2003 the .ico format was registered by Simon Butcher with the Internet Assigned Numbers Authority (IANA) under the MIME type image/vnd.microsoft.icon, finally standardizing the filetype.[3] (This also means that the filetype image/x-icon is no longer correct.)
Title: Re: You'd think shortcut would be quick
Post by: dedndave on January 17, 2010, 09:18:21 PM
you will see them both ways - the older mime type was in such wide use, it sort of became the standard without sanction
the "/x-????" types are used for mime types that are otherwise undefined, so it is essentially valid
of course, microsoft wants everyone to use their vnd.microsoft type - lol
during the "browser wars" of the late 90's/early 00's, that was a big issue between microsoft and netscape
Title: Re: You'd think shortcut would be quick
Post by: PBrennick on January 28, 2010, 09:43:59 PM
oex.

Attached is a program that will create links in either or all of the following three places: desktop, shortcut menu and/or rightclick menu. I also have a program that will remove them.

Paul
Title: Re: You'd think shortcut would be quick
Post by: donkey on January 29, 2010, 01:50:22 AM
Hi Paul,

Hard coding virtual folders can be problematic, you should use the API's to get the folder name for the desktop. For Vista and below use the CSIDL:

// From shlobj.h (GoAsm header project all versions)
#define CSIDL_DESKTOP 0

invoke SHGetSpecialFolderLocation, NULL, CSIDL_DESKTOP, offset PIDL
invoke SHGetPathFromIDListA,[PIDL],offset DesktopPath
invoke ILFree, [PIDL]


Note for ILFree you will have to call it by ordinal on Windows versions with Shell32 version 4.0:

// For GoAsm only:
invoke SHELL32.DLL:155, [PIDL]
// or define SHUSEORDINALS and set SHELLVER to WIN32_SHELL_40, the header project will automatically translate the call


For Win7 you should use Known Folders:

// From KnownFolders.h (GoAsm header project ver 0x020013 and above)
#DEFINE GUID_FOLDERID_Desktop <0xB4BFCC3A, 0xDB2C, 0x424C, <0xB0, 0x29, 0x7F, 0xE9, 0x9A, 0x87, 0xC6, 0x41>>

DATA SECTION
FOLDERID_Desktop GUID GUID_FOLDERID_Desktop

CODE SECTION
invoke SHGetKnownFolderPath, offset FOLDERID_Desktop, 0, NULL, offset DesktopPath

// free the path with CoTaskMemFree


Also, under UAC there may be problems writing to HKEY_CLASSES_ROOT, you are probably better off using a COM server to do the menu links. I have an example of an IContextMenu extension on my web site, I hope to get around to updating it and other examples to be UAC aware. I could be wrong about this though, it could just require a manifest or even not be an issue at all as I think HKEY_CLASSES_ROOT is virtualized anyway.

Edgar
Title: Re: You'd think shortcut would be quick
Post by: PBrennick on January 29, 2010, 05:28:57 AM
Hi Edgar,

If I remember correctly, ordinal calls are a problem when using masm32.

Paul

Title: Re: You'd think shortcut would be quick
Post by: hutch-- on January 29, 2010, 07:11:58 AM
Paul,

Its just a notation in the DEF file but due to senile decay and having lost the example, I forget how to do it. It may show up in a Microsoft Doc somewhere so I will have a look when I get the time.

Found it. http://msdn.microsoft.com/en-us/library/hyx1zcd3(VS.71).aspx
Title: Re: You'd think shortcut would be quick
Post by: jj2007 on January 29, 2010, 07:35:52 AM
Quote from: donkey on January 29, 2010, 01:50:22 AM
Hi Paul,

Hard coding virtual folders can be problematic, you should use the API's to get the folder name for the desktop. For Vista and below use the CSIDL:


I wonder if ExpandEnvironmentStrings works with all versions....

invoke ExpandEnvironmentStrings, chr$("%COMMONPROGRAMFILES%"), esi, MAX_PATH
Title: Re: You'd think shortcut would be quick
Post by: PBrennick on January 29, 2010, 01:32:27 PM
Edgar,

Yes, I just noticed there is a problem when you try it with Windows 7. This is a disappointment because that means my Sudoku Installer is broken ...

Paul
Title: Re: You'd think shortcut would be quick
Post by: donkey on January 29, 2010, 02:24:54 PM
Quote from: PBrennick on January 29, 2010, 05:28:57 AM
Hi Edgar,

If I remember correctly, ordinal calls are a problem when using masm32.

Paul



Hi Paul,

To call an ordinal from MASM you have to use GetProcAddress...

; Shell32.DLL is always loaded so no need for LoadLibrary
invoke GetModuleHandle, offset szShell32DllName
; Do not free the returned module handle, we did not increment the reference count
invoke GetProcAddress, eax, 155 ; using a value and not a pointer will obtain an ordinal address
mov pILFree, eax

; Because it is not possible to PROTO an ordinal call you can't use INVOKE
push PIDL
call pILFree


Edgar
Title: Re: You'd think shortcut would be quick
Post by: donkey on January 29, 2010, 02:40:22 PM
Quote from: jj2007 on January 29, 2010, 07:35:52 AM
I wonder if ExpandEnvironmentStrings works with all versions....

invoke ExpandEnvironmentStrings, chr$("%COMMONPROGRAMFILES%"), esi, MAX_PATH

Yes, ExpandEnvironmentStrings works with all versions including Win7, however many virtual folders are not identified by environment variables, the proper method to get the folder location is using the CSIDL or Known Folders. For example I don't believe the desktop is available, the only paths I know that are guaranteed to be present are:

%WINDIR%, %USERPROFILE%, %SYSTEMROOT%, %TEMP%, %PROGRAMFILES%, %HOMEPATH%, %APPDATA% and %ALLUSERSPROFILE%

As well as a few paths to applications such as cmd.exe (%COMSPEC%) and drives (%SYSTEMDRIVE% and %HOMEDRIVE%).

So by using ExpandEnvironmentStrings you are severely limiting the allowable destinations for your app, especially since many of the ones available are virtualized or simply not allowed under UAC.

Title: Re: You'd think shortcut would be quick
Post by: donkey on January 29, 2010, 03:30:53 PM
Quote from: PBrennick on January 29, 2010, 01:32:27 PM
Edgar,

Yes, I just noticed there is a problem when you try it with Windows 7. This is a disappointment because that means my Sudoku Installer is broken ...

Paul


Hi Paul, try an elevation manifest in the installer, also if you name the installer setup.exe, Win7 will recognize it as an installer and will present the elevation dialog when it is run. This behavior was added specifically for legacy installers and may solve your problem by itself. I am not familiar with your sudoku app (I don't really like sudoku so I never looked at it) but if its installer has any name other than install.exe or setup.exe Windows may not recognize it as an installation program.

For the HKEY_CLASSES_ROOT problem you should really use the user classes root but if you give your installer admin privileges you may be able to write to the system root.

Elevation manifest for admin privileges (note that asInvoker is generally sufficient):

<?xml version="1.0" encoding="UTF-16" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
  <assemblyIdentity version="1.0.0.0"
     processorArchitecture="X86" name="AdminApp" type="win32"/>
  <description>Description of your application</description>
  <!-- Identify the application security requirements. -->
  <ms_asmv2:trustInfo xmlns:ms_asmv2="urn:schemas-microsoft-com:asm.v2">
    <ms_asmv2:security>
      <ms_asmv2:requestedPrivileges>
        <ms_asmv2:requestedExecutionLevel
          level="requireAdministrator"
          uiAccess="false"/>
        </ms_asmv2:requestedPrivileges>
       </ms_asmv2:security>
  </ms_asmv2:trustInfo>
</assembly>
Title: Re: You'd think shortcut would be quick
Post by: dedndave on January 29, 2010, 05:29:19 PM
hiya Edgar
i noticed a comment about not being able to INVOKE an ordinal
couldn't this method be used ? (i think it was Erol that wrote it)

.data

kernel32    db 'kernel32.dll',0
FuncName    db 'SetConsoleIcon',0
msg         db 'Click the message box to change the console icon',0
msg2        db 'Console icon changed',0
capt        db 'Test',0
func        db 0FFh,025h ; define a jump entry
            dd pFunc

.data?

hIcon       dd ?
pFunc       dd ?

SetConsoleIcon  EQU <pr1 PTR func>

.code

start:
    invoke  GetModuleHandle,0
    invoke  LoadIcon,eax,200
    mov     hIcon,eax
    invoke  GetModuleHandle,ADDR kernel32
    invoke  GetProcAddress,eax,ADDR FuncName
    mov     pFunc,eax
    invoke  MessageBox,0,ADDR msg,ADDR capt,MB_OK
    invoke  SetConsoleIcon,hIcon
    invoke  MessageBox,0,ADDR msg2,ADDR capt,MB_OK
    invoke  ExitProcess,0

END start

this example shows how to INVOKE the undocumented SetConsoleIcon function
but, i think the idea is the same
Title: Re: You'd think shortcut would be quick
Post by: donkey on January 29, 2010, 07:33:00 PM
Quote from: dedndave on January 29, 2010, 05:29:19 PM
hiya Edgar
i noticed a comment about not being able to INVOKE an ordinal
couldn't this method be used ? (i think it was Erol that wrote it)...

Hi Dave,

Yeah, that looks like it works though I don't have MASM installed to try it. I was just going on memory and its been a long long time since I've used MASM. Still much easier with GoAsm since it loads the DLL at the PELoader stage but it seems to be unencumbered in MASM with that method. However, no PROTO so I wasn't too far off  :wink

Edgar
Title: Re: You'd think shortcut would be quick
Post by: dedndave on January 29, 2010, 11:11:51 PM
actually, your comment was "no PROTO", to begin with Edgar, so you had it right - i just read more into it   :U
it is interesting how the <pr1 PTR funcName> works, though
it gives me some food for thought   :P
Title: Re: You'd think shortcut would be quick
Post by: donkey on January 30, 2010, 04:16:04 AM
Quote from: dedndave on January 29, 2010, 11:11:51 PM
actually, your comment was "no PROTO", to begin with Edgar, so you had it right - i just read more into it   :U
it is interesting how the <pr1 PTR funcName> works, though
it gives me some food for thought   :P

Some interesting stuff you can do with that, for example support multiple DLL versions in the same executable. Its a shame MASM doesn't have an UNDEF directive for prototypes though, it would make things much neater.

ILFree2  EQU <pr1 PTR func>
GetMajorVersion PROTO :DWORD

.data
Shell32 db 'Shell32.dll',0
FuncName db 'ILFree',0
func db 0FFh,025h ; define a jump entry
dd pILFree

.data?

hModule dd ?
pILFree dd ?
PIDL dd 16 DUP (?)
DesktopPath DB MAX_PATH DUP (?)

.code
start:

invoke  GetModuleHandle,ADDR Shell32
mov hModule, eax

invoke GetMajorVersion,offset Shell32

.IF eax <= 4
invoke  GetProcAddress,hModule,155
.ELSE
invoke  GetProcAddress,hModule,offset FuncName
.ENDIF
mov     pILFree,eax

invoke SHGetSpecialFolderLocation, NULL, CSIDL_DESKTOP, offset PIDL
invoke SHGetPathFromIDListA,[PIDL],offset DesktopPath
invoke ILFree2, [PIDL]

invoke  MessageBox,0,ADDR DesktopPath,NULL,MB_OK
invoke  ExitProcess,0

GetMajorVersion PROC uses ebx esi pFileName
LOCAL Verification :DWORD
LOCAL RootPath :DWORD
LOCAL pVersion :DWORD
LOCAL pVersionLen :DWORD

invoke GetFileVersionInfoSize,pFileName,ADDR Verification
mov ebx,eax
test eax,eax
jz ERROR2

invoke GlobalAlloc,040h,eax
test eax,eax
jz ERROR2
xchg ebx,eax

invoke GetFileVersionInfo,[pFileName],0,eax,ebx
test eax,eax
jz ERROR1

mov DWORD PTR RootPath,"\"
invoke VerQueryValue,ebx,ADDR RootPath,ADDR pVersion,ADDR pVersionLen
test eax,eax
jz ERROR1

mov esi,[pVersion]
mov eax,[esi+VS_FIXEDFILEINFO.dwFileVersionMS]
shr eax,16
ERROR1:
push eax
invoke GlobalFree,ebx
pop eax
ERROR2:
RET
GetMajorVersion ENDP


Actually installed MASM to test it  :bg

Edgar

EDIT - made the GetMajorVersion procedure a little more robust
Title: Re: You'd think shortcut would be quick
Post by: dedndave on January 30, 2010, 09:27:10 AM
well - that was Erol's way to do it   :bg
combining Erol and Edgar is like having a pair of aces   :U