Changeset 1470 for trunk/src


Ignore:
Timestamp:
Oct 27, 1999, 11:33:48 AM (26 years ago)
Author:
phaller
Message:

Fix: debug info

Location:
trunk/src/shell32
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/shell32/resource.asm

    r1398 r1470  
    22;/* Source : shres.rc */
    33;/* Cmdline: wrc -s -I. -ID:\IBMCPP\include -I..\..\include -I..\..\include\win -o resource.asm shres.rc */
    4 ;/* Date   : Tue Oct 19 20:15:43 1999 */
     4;/* Date   : Mon Oct 25 10:23:09 1999 */
    55
    66        .386p
     
    1212        public  _Resource_PEResTab
    1313        dd      0
    14         dd      0380cc35fh
     14        dd      03814217dh
    1515        dd      0
    1616        dw      0, 6
     
    2929L3:
    3030        dd      0
    31         dd      0380cc35fh
     31        dd      03814217dh
    3232        dd      0
    3333        dw      0, 16
     
    6666L4:
    6767        dd      0
    68         dd      0380cc35fh
     68        dd      03814217dh
    6969        dd      0
    7070        dw      3, 0
     
    7777L5:
    7878        dd      0
    79         dd      0380cc35fh
     79        dd      03814217dh
    8080        dd      0
    8181        dw      2, 0
     
    8686L6:
    8787        dd      0
    88         dd      0380cc35fh
     88        dd      03814217dh
    8989        dd      0
    9090        dw      0, 2
     
    9595L14:
    9696        dd      0
    97         dd      0380cc35fh
     97        dd      03814217dh
    9898        dd      0
    9999        dw      0, 5
     
    110110L16:
    111111        dd      0
    112         dd      0380cc35fh
     112        dd      03814217dh
    113113        dd      0
    114114        dw      0, 1
     
    117117L3_1:
    118118        dd      0
    119         dd      0380cc35fh
     119        dd      03814217dh
    120120        dd      0
    121121        dw      0, 1
     
    124124L3_2:
    125125        dd      0
    126         dd      0380cc35fh
     126        dd      03814217dh
    127127        dd      0
    128128        dw      0, 1
     
    131131L3_3:
    132132        dd      0
    133         dd      0380cc35fh
     133        dd      03814217dh
    134134        dd      0
    135135        dw      0, 1
     
    138138L3_4:
    139139        dd      0
    140         dd      0380cc35fh
     140        dd      03814217dh
    141141        dd      0
    142142        dw      0, 1
     
    145145L3_5:
    146146        dd      0
    147         dd      0380cc35fh
     147        dd      03814217dh
    148148        dd      0
    149149        dw      0, 1
     
    152152L3_6:
    153153        dd      0
    154         dd      0380cc35fh
     154        dd      03814217dh
    155155        dd      0
    156156        dw      0, 1
     
    159159L3_7:
    160160        dd      0
    161         dd      0380cc35fh
     161        dd      03814217dh
    162162        dd      0
    163163        dw      0, 1
     
    166166L3_8:
    167167        dd      0
    168         dd      0380cc35fh
     168        dd      03814217dh
    169169        dd      0
    170170        dw      0, 1
     
    173173L3_9:
    174174        dd      0
    175         dd      0380cc35fh
     175        dd      03814217dh
    176176        dd      0
    177177        dw      0, 1
     
    180180L3_10:
    181181        dd      0
    182         dd      0380cc35fh
     182        dd      03814217dh
    183183        dd      0
    184184        dw      0, 1
     
    187187L3_11:
    188188        dd      0
    189         dd      0380cc35fh
     189        dd      03814217dh
    190190        dd      0
    191191        dw      0, 1
     
    194194L3_12:
    195195        dd      0
    196         dd      0380cc35fh
     196        dd      03814217dh
    197197        dd      0
    198198        dw      0, 1
     
    201201L3_13:
    202202        dd      0
    203         dd      0380cc35fh
     203        dd      03814217dh
    204204        dd      0
    205205        dw      0, 1
     
    208208L3_14:
    209209        dd      0
    210         dd      0380cc35fh
     210        dd      03814217dh
    211211        dd      0
    212212        dw      0, 1
     
    215215L3_15:
    216216        dd      0
    217         dd      0380cc35fh
     217        dd      03814217dh
    218218        dd      0
    219219        dw      0, 1
     
    222222L3_16:
    223223        dd      0
    224         dd      0380cc35fh
     224        dd      03814217dh
    225225        dd      0
    226226        dw      0, 1
     
    229229L4_MENU_001:
    230230        dd      0
    231         dd      0380cc35fh
     231        dd      03814217dh
    232232        dd      0
    233233        dw      0, 1
     
    236236L4_MENU_002:
    237237        dd      0
    238         dd      0380cc35fh
     238        dd      03814217dh
    239239        dd      0
    240240        dw      0, 1
     
    243243L4_MENU_SHV_FILE:
    244244        dd      0
    245         dd      0380cc35fh
     245        dd      03814217dh
    246246        dd      0
    247247        dw      0, 1
     
    250250L5_SHBRSFORFOLDER_MSGBOX:
    251251        dd      0
    252         dd      0380cc35fh
     252        dd      03814217dh
    253253        dd      0
    254254        dw      0, 1
     
    257257L5_SHELL_ABOUT_MSGBOX:
    258258        dd      0
    259         dd      0380cc35fh
     259        dd      03814217dh
    260260        dd      0
    261261        dw      0, 1
     
    264264L6_1:
    265265        dd      0
    266         dd      0380cc35fh
     266        dd      03814217dh
    267267        dd      0
    268268        dw      0, 1
     
    271271L6_2:
    272272        dd      0
    273         dd      0380cc35fh
     273        dd      03814217dh
    274274        dd      0
    275275        dw      0, 1
     
    278278L14_0:
    279279        dd      0
    280         dd      0380cc35fh
     280        dd      03814217dh
    281281        dd      0
    282282        dw      0, 1
     
    285285L14_3:
    286286        dd      0
    287         dd      0380cc35fh
     287        dd      03814217dh
    288288        dd      0
    289289        dw      0, 1
     
    292292L14_8:
    293293        dd      0
    294         dd      0380cc35fh
     294        dd      03814217dh
    295295        dd      0
    296296        dw      0, 1
     
    299299L14_15:
    300300        dd      0
    301         dd      0380cc35fh
     301        dd      03814217dh
    302302        dd      0
    303303        dw      0, 1
     
    306306L14_34:
    307307        dd      0
    308         dd      0380cc35fh
     308        dd      03814217dh
    309309        dd      0
    310310        dw      0, 1
     
    313313L16_1:
    314314        dd      0
    315         dd      0380cc35fh
     315        dd      03814217dh
    316316        dd      0
    317317        dw      0, 1
     
    462462L16_1_0:
    463463        dd      _Resource_VerInf_1_0_data - _Resource_PEResTab
    464         dd      812
     464        dd      760
    465465        dd      0
    466466        dd      0
     
    624624        align   4
    625625_Resource_VerInf_1_0_data:
    626         db      02ch, 003h, 034h, 000h, 000h, 000h, 056h, 000h
     626        db      0f8h, 002h, 034h, 000h, 000h, 000h, 056h, 000h
    627627        db      053h, 000h, 05fh, 000h, 056h, 000h, 045h, 000h
    628628        db      052h, 000h, 053h, 000h, 049h, 000h, 04fh, 000h
     
    635635        db      001h, 000h, 001h, 000h, 001h, 000h, 000h, 000h
    636636        db      000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
    637         db      000h, 000h, 000h, 000h, 08ch, 002h, 000h, 000h
     637        db      000h, 000h, 000h, 000h, 058h, 002h, 000h, 000h
    638638        db      000h, 000h, 053h, 000h, 074h, 000h, 072h, 000h
    639639        db      069h, 000h, 06eh, 000h, 067h, 000h, 046h, 000h
    640640        db      069h, 000h, 06ch, 000h, 065h, 000h, 049h, 000h
    641641        db      06eh, 000h, 066h, 000h, 06fh, 000h, 000h, 000h
    642         db      068h, 002h, 000h, 000h, 000h, 000h, 030h, 000h
     642        db      034h, 002h, 000h, 000h, 000h, 000h, 030h, 000h
    643643        db      034h, 000h, 030h, 000h, 039h, 000h, 030h, 000h
    644644        db      034h, 000h, 045h, 000h, 034h, 000h, 000h, 000h
     
    657657        db      069h, 000h, 06eh, 000h, 020h, 000h, 054h, 000h
    658658        db      065h, 000h, 061h, 000h, 06dh, 000h, 000h, 000h
    659         db      060h, 000h, 01ch, 000h, 001h, 000h, 046h, 000h
     659        db      02ah, 000h, 001h, 000h, 001h, 000h, 046h, 000h
    660660        db      069h, 000h, 06ch, 000h, 065h, 000h, 044h, 000h
    661661        db      065h, 000h, 073h, 000h, 063h, 000h, 072h, 000h
    662662        db      069h, 000h, 070h, 000h, 074h, 000h, 069h, 000h
    663663        db      06fh, 000h, 06eh, 000h, 000h, 000h, 000h, 000h
    664         db      047h, 000h, 065h, 000h, 06eh, 000h, 065h, 000h
    665         db      072h, 000h, 069h, 000h, 063h, 000h, 020h, 000h
    666         db      045h, 000h, 078h, 000h, 061h, 000h, 06dh, 000h
    667         db      070h, 000h, 06ch, 000h, 065h, 000h, 020h, 000h
    668         db      041h, 000h, 070h, 000h, 070h, 000h, 06ch, 000h
    669         db      069h, 000h, 063h, 000h, 061h, 000h, 074h, 000h
    670         db      069h, 000h, 06fh, 000h, 06eh, 000h, 000h, 000h
    671         db      028h, 000h, 004h, 000h, 001h, 000h, 046h, 000h
    672         db      069h, 000h, 06ch, 000h, 065h, 000h, 056h, 000h
    673         db      065h, 000h, 072h, 000h, 073h, 000h, 069h, 000h
    674         db      06fh, 000h, 06eh, 000h, 000h, 000h, 000h, 000h
    675         db      030h, 000h, 02eh, 000h, 030h, 000h, 000h, 000h
    676         db      042h, 000h, 011h, 000h, 001h, 000h, 049h, 000h
    677         db      06eh, 000h, 074h, 000h, 065h, 000h, 072h, 000h
    678         db      06eh, 000h, 061h, 000h, 06ch, 000h, 04eh, 000h
    679         db      061h, 000h, 06dh, 000h, 065h, 000h, 000h, 000h
    680         db      04fh, 000h, 064h, 000h, 069h, 000h, 06eh, 000h
    681         db      033h, 000h, 032h, 000h, 020h, 000h, 02dh, 000h
    682         db      020h, 000h, 053h, 000h, 048h, 000h, 045h, 000h
    683         db      04ch, 000h, 04ch, 000h, 033h, 000h, 032h, 000h
    684         db      000h, 000h, 000h, 000h, 04ah, 000h, 013h, 000h
    685         db      001h, 000h, 04ch, 000h, 065h, 000h, 067h, 000h
    686         db      061h, 000h, 06ch, 000h, 043h, 000h, 06fh, 000h
    687         db      070h, 000h, 079h, 000h, 072h, 000h, 069h, 000h
    688         db      067h, 000h, 068h, 000h, 074h, 000h, 000h, 000h
     664        db      000h, 000h, 000h, 000h, 028h, 000h, 004h, 000h
     665        db      001h, 000h, 046h, 000h, 069h, 000h, 06ch, 000h
     666        db      065h, 000h, 056h, 000h, 065h, 000h, 072h, 000h
     667        db      073h, 000h, 069h, 000h, 06fh, 000h, 06eh, 000h
     668        db      000h, 000h, 000h, 000h, 030h, 000h, 02eh, 000h
     669        db      030h, 000h, 000h, 000h, 042h, 000h, 011h, 000h
     670        db      001h, 000h, 049h, 000h, 06eh, 000h, 074h, 000h
     671        db      065h, 000h, 072h, 000h, 06eh, 000h, 061h, 000h
     672        db      06ch, 000h, 04eh, 000h, 061h, 000h, 06dh, 000h
     673        db      065h, 000h, 000h, 000h, 04fh, 000h, 064h, 000h
     674        db      069h, 000h, 06eh, 000h, 033h, 000h, 032h, 000h
     675        db      020h, 000h, 02dh, 000h, 020h, 000h, 053h, 000h
     676        db      048h, 000h, 045h, 000h, 04ch, 000h, 04ch, 000h
     677        db      033h, 000h, 032h, 000h, 000h, 000h, 000h, 000h
     678        db      04ah, 000h, 013h, 000h, 001h, 000h, 04ch, 000h
     679        db      065h, 000h, 067h, 000h, 061h, 000h, 06ch, 000h
    689680        db      043h, 000h, 06fh, 000h, 070h, 000h, 079h, 000h
    690681        db      072h, 000h, 069h, 000h, 067h, 000h, 068h, 000h
    691         db      074h, 000h, 020h, 000h, 028h, 000h, 043h, 000h
    692         db      029h, 000h, 020h, 000h, 031h, 000h, 039h, 000h
    693         db      039h, 000h, 039h, 000h, 000h, 000h, 000h, 000h
    694         db      02ah, 000h, 001h, 000h, 001h, 000h, 04ch, 000h
    695         db      065h, 000h, 067h, 000h, 061h, 000h, 06ch, 000h
    696         db      054h, 000h, 072h, 000h, 061h, 000h, 064h, 000h
    697         db      065h, 000h, 06dh, 000h, 061h, 000h, 072h, 000h
    698         db      06bh, 000h, 073h, 000h, 000h, 000h, 000h, 000h
     682        db      074h, 000h, 000h, 000h, 043h, 000h, 06fh, 000h
     683        db      070h, 000h, 079h, 000h, 072h, 000h, 069h, 000h
     684        db      067h, 000h, 068h, 000h, 074h, 000h, 020h, 000h
     685        db      028h, 000h, 043h, 000h, 029h, 000h, 020h, 000h
     686        db      031h, 000h, 039h, 000h, 039h, 000h, 039h, 000h
    699687        db      000h, 000h, 000h, 000h, 02ah, 000h, 001h, 000h
    700         db      001h, 000h, 04fh, 000h, 072h, 000h, 069h, 000h
    701         db      067h, 000h, 069h, 000h, 06eh, 000h, 061h, 000h
    702         db      06ch, 000h, 046h, 000h, 069h, 000h, 06ch, 000h
    703         db      065h, 000h, 06eh, 000h, 061h, 000h, 06dh, 000h
    704         db      065h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
    705         db      042h, 000h, 011h, 000h, 001h, 000h, 050h, 000h
    706         db      072h, 000h, 06fh, 000h, 064h, 000h, 075h, 000h
    707         db      063h, 000h, 074h, 000h, 04eh, 000h, 061h, 000h
    708         db      06dh, 000h, 065h, 000h, 000h, 000h, 000h, 000h
    709         db      04fh, 000h, 064h, 000h, 069h, 000h, 06eh, 000h
    710         db      033h, 000h, 032h, 000h, 020h, 000h, 02dh, 000h
    711         db      020h, 000h, 053h, 000h, 048h, 000h, 045h, 000h
    712         db      04ch, 000h, 04ch, 000h, 033h, 000h, 032h, 000h
    713         db      000h, 000h, 000h, 000h, 02ch, 000h, 004h, 000h
     688        db      001h, 000h, 04ch, 000h, 065h, 000h, 067h, 000h
     689        db      061h, 000h, 06ch, 000h, 054h, 000h, 072h, 000h
     690        db      061h, 000h, 064h, 000h, 065h, 000h, 06dh, 000h
     691        db      061h, 000h, 072h, 000h, 06bh, 000h, 073h, 000h
     692        db      000h, 000h, 000h, 000h, 000h, 000h, 000h, 000h
     693        db      02ah, 000h, 001h, 000h, 001h, 000h, 04fh, 000h
     694        db      072h, 000h, 069h, 000h, 067h, 000h, 069h, 000h
     695        db      06eh, 000h, 061h, 000h, 06ch, 000h, 046h, 000h
     696        db      069h, 000h, 06ch, 000h, 065h, 000h, 06eh, 000h
     697        db      061h, 000h, 06dh, 000h, 065h, 000h, 000h, 000h
     698        db      000h, 000h, 000h, 000h, 042h, 000h, 011h, 000h
    714699        db      001h, 000h, 050h, 000h, 072h, 000h, 06fh, 000h
    715700        db      064h, 000h, 075h, 000h, 063h, 000h, 074h, 000h
    716         db      056h, 000h, 065h, 000h, 072h, 000h, 073h, 000h
    717         db      069h, 000h, 06fh, 000h, 06eh, 000h, 000h, 000h
    718         db      031h, 000h, 02eh, 000h, 030h, 000h, 000h, 000h
    719         db      044h, 000h, 000h, 000h, 000h, 000h, 056h, 000h
    720         db      061h, 000h, 072h, 000h, 046h, 000h, 069h, 000h
    721         db      06ch, 000h, 065h, 000h, 049h, 000h, 06eh, 000h
    722         db      066h, 000h, 06fh, 000h, 000h, 000h, 000h, 000h
    723         db      024h, 000h, 004h, 000h, 000h, 000h, 054h, 000h
    724         db      072h, 000h, 061h, 000h, 06eh, 000h, 073h, 000h
    725         db      06ch, 000h, 061h, 000h, 074h, 000h, 069h, 000h
    726         db      06fh, 000h, 06eh, 000h, 000h, 000h, 000h, 000h
    727         db      009h, 004h, 0e4h, 004h
     701        db      04eh, 000h, 061h, 000h, 06dh, 000h, 065h, 000h
     702        db      000h, 000h, 000h, 000h, 04fh, 000h, 064h, 000h
     703        db      069h, 000h, 06eh, 000h, 033h, 000h, 032h, 000h
     704        db      020h, 000h, 02dh, 000h, 020h, 000h, 053h, 000h
     705        db      048h, 000h, 045h, 000h, 04ch, 000h, 04ch, 000h
     706        db      033h, 000h, 032h, 000h, 000h, 000h, 000h, 000h
     707        db      02ch, 000h, 004h, 000h, 001h, 000h, 050h, 000h
     708        db      072h, 000h, 06fh, 000h, 064h, 000h, 075h, 000h
     709        db      063h, 000h, 074h, 000h, 056h, 000h, 065h, 000h
     710        db      072h, 000h, 073h, 000h, 069h, 000h, 06fh, 000h
     711        db      06eh, 000h, 000h, 000h, 031h, 000h, 02eh, 000h
     712        db      030h, 000h, 000h, 000h, 044h, 000h, 000h, 000h
     713        db      000h, 000h, 056h, 000h, 061h, 000h, 072h, 000h
     714        db      046h, 000h, 069h, 000h, 06ch, 000h, 065h, 000h
     715        db      049h, 000h, 06eh, 000h, 066h, 000h, 06fh, 000h
     716        db      000h, 000h, 000h, 000h, 024h, 000h, 004h, 000h
     717        db      000h, 000h, 054h, 000h, 072h, 000h, 061h, 000h
     718        db      06eh, 000h, 073h, 000h, 06ch, 000h, 061h, 000h
     719        db      074h, 000h, 069h, 000h, 06fh, 000h, 06eh, 000h
     720        db      000h, 000h, 000h, 000h, 009h, 004h, 0e4h, 004h
    728721
    729722        align   4
  • trunk/src/shell32/shellpath.cpp

    r1215 r1470  
    1 /* $Id: shellpath.cpp,v 1.2 1999-10-09 11:17:05 sandervl Exp $ */
    2 /*
    3  * Path Functions
    4  *
    5  * Many of this functions are in SHLWAPI.DLL also
    6  *
    7  */
    8 #include <string.h>
    9 #include <ctype.h>
    10 #include <wctype.h>
    11 #define HAVE_WCTYPE_H
    12 #include <odin.h>
     1/* $Id: shellpath.cpp,v 1.3 1999-10-27 09:33:48 phaller Exp $ */
     2 
     3/*
     4 * Win32 SHELL32 for OS/2
     5 *
     6 * Copyright 1997 Marcus Meissner
     7 * Copyright 1999 Patrick Haller (haller@zebra.fh-weingarten.de)
     8 * Project Odin Software License can be found in LICENSE.TXT
     9 *
     10 * Path Functions
     11 *
     12 * Many of this functions are in SHLWAPI.DLL also
     13 *
     14 */
     15 
     16 
     17/*****************************************************************************
     18 * Includes                                                                  *
     19 *****************************************************************************/
     20 
     21#include <odin.h>
     22#include <odinwrap.h>
     23#include <os2sel.h>
     24 
     25#include <string.h>
     26#include <ctype.h>
     27#include <wctype.h>
     28#define HAVE_WCTYPE_H
     29#include <odin.h>
     30 
     31#define ICOM_CINTERFACE 1
     32#define CINTERFACE 1
     33 
     34#include "debugtools.h"
     35#include "winnls.h"
     36#include "winversion.h"
     37#include "winreg.h"
     38#include "crtdll.h"
     39 
     40#include "shlobj.h"
     41#include "shell32_main.h"
     42 
     43#include <heapstring.h>
     44#include <misc.h>
     45 
     46 
     47ODINDEBUGCHANNEL(SHELL32-SHELLPATH)
     48 
     49 
     50/*************************************************************************
     51 * PathIsRoot [SHELL32.29]
     52 */
     53ODINFUNCTION1(BOOL, PathIsRootA,
     54              LPCSTR, x)
     55{  TRACE("%s\n",x);
     56   if (*(x+1)==':' && *(x+2)=='\\')         /* "X:\" */
     57     return 1;
     58   if (*x=='\\')                         /* "\" */
     59     return 0;
     60   if (x[0]=='\\' && x[1]=='\\')            /* UNC "\\<xx>\" */
     61   { int foundbackslash = 0;
     62     x=x+2;
     63     while (*x)
     64     { if (*x++=='\\')
     65         foundbackslash++;
     66     }
     67     if (foundbackslash<=1)              /* max 1 \ more ... */
     68       return 1;
     69   }
     70   return 0;
     71}
     72ODINFUNCTION1(BOOL, PathIsRootW,
     73              LPCWSTR, x)
     74{  TRACE("%s\n",debugstr_w(x));
     75   if (*(x+1)==':' && *(x+2)=='\\')         /* "X:\" */
     76     return 1;
     77   if (*x == (WCHAR) '\\')                  /* "\" */
     78     return 0;
     79   if (x[0]==(WCHAR)'\\' && x[1]==(WCHAR)'\\') /* UNC "\\<xx>\" */
     80   { int foundbackslash = 0;
     81     x=x+2;
     82     while (*x)
     83     { if (*x++==(WCHAR)'\\')
     84         foundbackslash++;
     85     }
     86     if (foundbackslash<=1)              /* max 1 \ more ... */
     87       return 1;
     88   }
     89   return 0;
     90}
     91ODINFUNCTION1(BOOL, PathIsRootAW,
     92              LPCVOID, x)
     93{  if (VERSION_OsIsUnicode())
     94     return PathIsRootW((LPWSTR)x);
     95   return PathIsRootA((LPSTR)x);
     96 
     97}
     98/*************************************************************************
     99 * PathBuildRoot [SHELL32.30]
     100 */
     101ODINFUNCTION2(LPSTR, PathBuildRootA,
     102              LPSTR, root,
     103              BYTE, drive)
     104{
     105  TRACE("%p %i\n",root, drive);
     106   strcpy(root,"A:\\");
     107   root[0]+=drive;
     108   return root;
     109}
     110 
     111/*************************************************************************
     112 * PathFindExtension [SHELL32.31]
     113 *
     114 * NOTES
     115 *     returns pointer to last . in last pathcomponent or at \0.
     116 */
     117ODINFUNCTION1(LPCSTR, PathFindExtensionA,
     118              LPCSTR, path)
     119{  LPCSTR   lastpoint = NULL;
     120   TRACE("%p %s\n",path,path);
     121   while (*path)
     122   { if (*path=='\\'||*path==' ')
     123       lastpoint=NULL;
     124     if (*path=='.')
     125       lastpoint=path;
     126     path++;
     127   }
     128   return lastpoint?lastpoint:path;
     129}
     130ODINFUNCTION1(LPCWSTR, PathFindExtensionW,
     131              LPCWSTR, path)
     132{  LPCWSTR   lastpoint = NULL;
     133   TRACE("%p L%s\n",path,debugstr_w(path));
     134   while (*path)
     135   { if (*path==(WCHAR)'\\'||*path==(WCHAR)' ')
     136       lastpoint=NULL;
     137     if (*path==(WCHAR)'.')
     138       lastpoint=path;
     139     path++;
     140   }
     141   return lastpoint?lastpoint:path;
     142}
     143ODINFUNCTION1(LPCVOID, PathFindExtensionAW,
     144              LPCVOID, path)
     145{  if (VERSION_OsIsUnicode())
     146     return PathFindExtensionW((LPWSTR)path);
     147   return PathFindExtensionA((LPSTR)path);
     148 
     149}
     150 
     151/*************************************************************************
     152 * PathAddBackslash [SHELL32.32]
     153 *
     154 * NOTES
     155 *     append \ if there is none
     156 */
     157ODINFUNCTION1(LPSTR, PathAddBackslashA,
     158              LPSTR, path)
     159{  int len;
     160   TRACE("%p->%s\n",path,path);
     161 
     162   len = strlen(path);
     163   if (len && path[len-1]!='\\')
     164   { path[len]  = '\\';
     165     path[len+1]= 0x00;
     166     return path+len+1;
     167   }
     168   return path+len;
     169}
     170ODINFUNCTION1(LPWSTR, PathAddBackslashW,
     171              LPWSTR, path)
     172{  int len;
     173   TRACE("%p->%s\n",path,debugstr_w(path));
     174 
     175   len = lstrlenW(path);
     176   if (len && path[len-1]!=(WCHAR)'\\')
     177   { path[len]  = (WCHAR)'\\';
     178     path[len+1]= 0x00;
     179     return path+len+1;
     180   }
     181   return path+len;
     182}
     183ODINFUNCTION1(LPVOID, PathAddBackslashAW,
     184              LPVOID, path)
     185{  if(VERSION_OsIsUnicode())
     186     return PathAddBackslashW((LPWSTR)path);
     187   return PathAddBackslashA((LPSTR)path);
     188}
     189 
     190/*************************************************************************
     191 * PathRemoveBlanks [SHELL32.33]
     192 *
     193 * NOTES
     194 *     remove spaces from beginning and end of passed string
     195 */
     196ODINFUNCTION1(LPSTR, PathRemoveBlanksA,
     197              LPSTR, str)
     198{  LPSTR x = str;
     199   TRACE("%s\n",str);
     200   while (*x==' ') x++;
     201   if (x!=str)
     202     strcpy(str,x);
     203   if (!*str)
     204     return str;
     205   x=str+strlen(str)-1;
     206   while (*x==' ')
     207     x--;
     208   if (*x==' ')
     209     *x='\0';
     210   return x;
     211}
     212ODINFUNCTION1(LPWSTR, PathRemoveBlanksW,
     213              LPWSTR, str)
     214{  LPWSTR x = str;
     215   TRACE("%s\n",debugstr_w(str));
     216   while (*x==' ') x++;
     217   if (x!=str)
     218     lstrcpyW(str,x);
     219   if (!*str)
     220     return str;
     221   x=str+lstrlenW(str)-1;
     222   while (*x==' ')
     223     x--;
     224   if (*x==' ')
     225     *x='\0';
     226   return x;
     227}
     228ODINFUNCTION1(LPVOID, PathRemoveBlanksAW,
     229              LPVOID, str)
     230{  if(VERSION_OsIsUnicode())
     231     return PathRemoveBlanksW((LPWSTR)str);
     232   return PathRemoveBlanksA((LPSTR)str);
     233}
     234 
     235 
     236 
     237/*************************************************************************
     238 * PathFindFilename [SHELL32.34]
     239 *
     240 * NOTES
     241 *     basename(char *fn);
     242 */
     243ODINFUNCTION1(LPCSTR, PathFindFilenameA,
     244              LPCSTR, aptr)
     245{  LPCSTR aslash;
     246   aslash = aptr;
     247 
     248   TRACE("%s\n",aslash);
     249   while (aptr[0])
     250   { if (((aptr[0]=='\\') || (aptr[0]==':')) && aptr[1] && aptr[1]!='\\')
     251         aslash = aptr+1;
     252     aptr++;
     253   }
     254   return aslash;
     255 
     256}
     257ODINFUNCTION1(LPCWSTR, PathFindFilenameW,
     258              LPCWSTR, wptr)
     259{  LPCWSTR wslash;
     260   wslash = wptr;
     261 
     262   TRACE("L%s\n",debugstr_w(wslash));
     263   while (wptr[0])
     264   { if (((wptr[0]=='\\') || (wptr[0]==':')) && wptr[1] && wptr[1]!='\\')
     265       wslash = wptr+1;
     266     wptr++;
     267   }
     268   return wslash;
     269}
     270ODINFUNCTION1(LPCVOID, PathFindFilenameAW,
     271              LPCVOID, fn)
     272{
     273   if(VERSION_OsIsUnicode())
     274     return PathFindFilenameW((LPWSTR)fn);
     275   return PathFindFilenameA((LPSTR)fn);
     276}
     277 
     278/*************************************************************************
     279 * PathRemoveFileSpec [SHELL32.35]
     280 *
     281 * NOTES
     282 *     bool getpath(char *pathname); truncates passed argument to a valid path
     283 *     returns if the string was modified or not.
     284 *     "\foo\xx\foo"-> "\foo\xx"
     285 *     "\" -> "\"
     286 *     "a:\foo"   -> "a:\"
     287 */
     288ODINFUNCTION1(DWORD, PathRemoveFileSpecA,
     289              LPSTR, fn)
     290{
     291   LPSTR x,cutplace;
     292  TRACE("%s\n",fn);
     293   if (!fn[0])
     294      return 0;
     295   x=fn;
     296   cutplace = fn;
     297   while (*x) {
     298      if (*x=='\\') {
     299         cutplace=x++;
     300         continue;
     301      }
     302      if (*x==':') {
     303         x++;
     304         if (*x=='\\')
     305            cutplace=++x;
     306         continue; /* already x++ed */
     307      }
     308      x++;
     309   }
     310   if (!*cutplace)
     311      return 0;
     312   if (cutplace==fn) {
     313      if (fn[0]=='\\') {
     314         if (!fn[1])
     315            return 0;
     316         fn[0]='\0';
     317         return 1;
     318      }
     319   }
     320   *cutplace='\0';
     321   return 1;
     322}
     323 
     324/*************************************************************************
     325 * PathAppend [SHELL32.36]
     326 *
     327 * NOTES
     328 *     concat_paths(char*target,const char*add);
     329 *     concats "target\\add" and writes them to target
     330 */
     331ODINFUNCTION2(LPSTR, PathAppendA,
     332              LPSTR, x1,
     333              LPSTR, x2)
     334{
     335  TRACE("%s %s\n",x1,x2);
     336  while (x2[0]=='\\') x2++;
     337  return PathCombineA(x1,x1,x2);
     338}
     339 
     340/*************************************************************************
     341 * PathCombine [SHELL32.37]
     342 *
     343 * NOTES
     344 *  if lpszFile='.' skip it
     345 *  szDest can be equal to lpszFile. Thats why we use sTemp
     346 */
     347ODINFUNCTION3(LPSTR, PathCombineA,
     348              LPSTR, szDest,
     349              LPCSTR, lpszDir,
     350              LPCSTR, lpszFile)
     351{  char sTemp[MAX_PATH];
     352   TRACE("%p %p->%s %p->%s\n",szDest, lpszDir, lpszDir, lpszFile, lpszFile);
     353 
     354 
     355   if (!lpszFile || !lpszFile[0] || (lpszFile[0]=='.' && !lpszFile[1]) )
     356   { strcpy(szDest,lpszDir);
     357     return szDest;
     358   }
     359 
     360   /*  if lpszFile is a complete path don't care about lpszDir */
     361   if (PathIsRootA(lpszFile))
     362   { strcpy(szDest,lpszFile);
     363   }
     364   else
     365   { strcpy(sTemp,lpszDir);
     366     PathAddBackslashA(sTemp);
     367     strcat(sTemp,lpszFile);
     368     strcpy(szDest,sTemp);
     369   }
     370   return szDest;
     371}
     372ODINFUNCTION3(LPWSTR, PathCombineW,
     373              LPWSTR, szDest,
     374              LPCWSTR, lpszDir,
     375              LPCWSTR, lpszFile)
     376{  WCHAR sTemp[MAX_PATH];
     377   TRACE("%p %p->%s %p->%s\n",szDest, lpszDir, debugstr_w(lpszDir),
     378          lpszFile, debugstr_w(lpszFile));
     379 
     380 
     381   if (!lpszFile || !lpszFile[0] || (lpszFile[0]==(WCHAR)'.' && !lpszFile[1]) )
     382   { lstrcpyW(szDest,lpszDir);
     383     return szDest;
     384   }
     385 
     386   /*  if lpszFile is a complete path don't care about lpszDir */
     387   if (PathIsRootW(lpszFile))
     388   { lstrcpyW(szDest,lpszFile);
     389   }
     390   else
     391   { lstrcpyW(sTemp,lpszDir);
     392     PathAddBackslashW(sTemp);
     393     lstrcatW(sTemp,lpszFile);
     394     lstrcpyW(szDest,sTemp);
     395   }
     396   return szDest;
     397}
     398ODINFUNCTION3(LPVOID, PathCombineAW,
     399              LPVOID, szDest,
     400              LPCVOID, lpszDir,
     401              LPCVOID, lpszFile)
     402{  if (VERSION_OsIsUnicode())
     403     return PathCombineW( (LPWSTR)szDest, (LPWSTR)lpszDir, (LPWSTR)lpszFile );
     404   return PathCombineA( (LPSTR)szDest, (LPSTR)lpszDir, (LPSTR)lpszFile );
     405}
     406 
     407/*************************************************************************
     408 * PathIsUNC [SHELL32.39]
     409 *
     410 * NOTES
     411 *     PathIsUNC(char*path);
     412 */
     413ODINFUNCTION1(BOOL, PathIsUNCA,
     414              LPCSTR, path)
     415{  TRACE("%s\n",path);
     416 
     417   if ((path[0]=='\\') && (path[1]=='\\'))
     418     return TRUE;
     419   return FALSE;
     420}
     421ODINFUNCTION1(BOOL, PathIsUNCW,
     422              LPCWSTR, path)
     423{  TRACE("%s\n",debugstr_w(path));
     424 
     425   if ((path[0]=='\\') && (path[1]=='\\'))
     426     return TRUE;
     427   return FALSE;
     428}
     429ODINFUNCTION1(BOOL, PathIsUNCAW,
     430              LPCVOID, path)
     431{  if (VERSION_OsIsUnicode())
     432     return PathIsUNCW( (LPWSTR)path );
     433   return PathIsUNCA( (LPSTR)path );
     434}
     435/*************************************************************************
     436 *  PathIsRelativ [SHELL32.40]
     437 *
     438 */
     439ODINFUNCTION1(BOOL, PathIsRelativeA,
     440              LPCSTR, path)
     441{  TRACE("path=%s\n",path);
     442 
     443   if (path && (path[0]!='\\' && path[1]==':'))
     444     return TRUE;
     445   return FALSE;
     446}
     447ODINFUNCTION1(BOOL, PathIsRelativeW,
     448              LPCWSTR, path)
     449{  TRACE("path=%s\n",debugstr_w(path));
     450 
     451   if (path && (path[0]!='\\' && path[1]==':'))
     452     return TRUE;
     453   return FALSE;
     454}
     455ODINFUNCTION1(BOOL, PathIsRelativeAW,
     456              LPCVOID, path)
     457{  if (VERSION_OsIsUnicode())
     458     return PathIsRelativeW( (LPWSTR)path );
     459   return PathIsRelativeA( (LPSTR)path );
     460}
     461/*************************************************************************
     462 *  PathIsExe [SHELL32.43]
     463 *
     464 */
     465ODINFUNCTION1(BOOL, PathIsExeA,
     466              LPCSTR, path)
     467{  FIXME("path=%s\n",path);
     468   return FALSE;
     469}
     470ODINFUNCTION1(BOOL, PathIsExeW,
     471              LPCWSTR, path)
     472{  FIXME("path=%s\n",debugstr_w(path));
     473   return FALSE;
     474}
     475ODINFUNCTION1(BOOL, PathIsExeAW,
     476              LPCVOID, path)
     477{  if (VERSION_OsIsUnicode())
     478     return PathIsExeW ((LPWSTR)path);
     479   return PathIsExeA((LPSTR)path);
     480}
     481 
     482/*************************************************************************
     483 * PathFileExists [SHELL32.45]
     484 *
     485 * NOTES
     486 *     file_exists(char *fn);
     487 */
     488ODINFUNCTION1(BOOL, PathFileExistsA,
     489              LPSTR, fn)
     490{
     491  TRACE("%s\n",fn);
     492   if (GetFileAttributesA(fn)==-1)
     493      return FALSE;
     494    else
     495      return TRUE;
     496}
     497/*************************************************************************
     498 * PathMatchSingleMask
     499 *
     500 * NOTES
     501 *     internal (used by PathMatchSpec)
     502 */
     503static BOOL PathMatchSingleMaskA(LPCSTR name, LPCSTR mask)
     504{
     505  while (*name && *mask && *mask!=';') {
     506    if (*mask=='*') {
     507      do {
     508   if (PathMatchSingleMaskA(name,mask+1)) return 1;  /* try substrings */
     509      } while (*name++);
     510      return 0;
     511    }
     512    if (toupper(*mask)!=toupper(*name) && *mask!='?') return 0;
     513    name++;
     514    mask++;
     515  }
     516  if (!*name) {
     517    while (*mask=='*') mask++;
     518    if (!*mask || *mask==';') return 1;
     519  }
     520  return 0;
     521}
     522static BOOL PathMatchSingleMaskW(LPCWSTR name, LPCWSTR mask)
     523{
     524  while (*name && *mask && *mask!=';') {
     525    if (*mask=='*') {
     526      do {
     527   if (PathMatchSingleMaskW(name,mask+1)) return 1;  /* try substrings */
     528      } while (*name++);
     529      return 0;
     530    }
     531    if (towupper(*mask)!=towupper(*name) && *mask!='?') return 0;
     532    name++;
     533    mask++;
     534  }
     535  if (!*name) {
     536    while (*mask=='*') mask++;
     537    if (!*mask || *mask==';') return 1;
     538  }
     539  return 0;
     540}
     541/*************************************************************************
     542 * PathMatchSpec [SHELL32.46]
     543 *
     544 * NOTES
     545 *     used from COMDLG32
     546 */
     547ODINFUNCTION2(BOOL, PathMatchSpecA,
     548              LPCSTR, name,
     549              LPCSTR, mask)
     550{
     551  TRACE("%s %s\n",name,mask);
     552 
     553  if (!lstrcmpA( mask, "*.*" )) return 1;   /* we don't require a period */
     554 
     555  while (*mask) {
     556    if (PathMatchSingleMaskA(name,mask)) return 1;    /* helper function */
     557    while (*mask && *mask!=';') mask++;
     558    if (*mask==';') {
     559      mask++;
     560      while (*mask==' ') mask++;      /*  masks may be separated by "; " */
     561     }
     562   }
     563  return 0;
     564}
     565ODINFUNCTION2(BOOL, PathMatchSpecW,
     566              LPCWSTR, name,
     567              LPCWSTR, mask)
     568{  WCHAR stemp[4];
     569  TRACE("%ls %ls\n",name,mask);
     570   lstrcpyAtoW(stemp,"*.*");
     571  if (!lstrcmpW( mask, stemp )) return 1;   /* we don't require a period */
     572 
     573  while (*mask) {
     574    if (PathMatchSingleMaskW(name,mask)) return 1;    /* helper function */
     575    while (*mask && *mask!=';') mask++;
     576    if (*mask==';') {
     577      mask++;
     578      while (*mask==' ') mask++;       /* masks may be separated by "; " */
     579     }
     580   }
     581  return 0;
     582}
     583ODINFUNCTION2(BOOL, PathMatchSpecAW,
     584              LPVOID, name,
     585              LPVOID, mask)
     586{  if (VERSION_OsIsUnicode())
     587     return PathMatchSpecW( (LPWSTR)name, (LPWSTR)mask );
     588   return PathMatchSpecA( (LPSTR)name, (LPSTR)mask );
     589}
     590/*************************************************************************
     591 * PathSetDlgItemPathAW [SHELL32.48]
     592 * NOTES
     593 *  use PathCompactPath to make sure, the path fits into the control
     594 */
     595 
     596ODINFUNCTION3(BOOL, PathSetDlgItemPathA,
     597              HWND, hDlg,
     598              int, id,
     599              LPCSTR, pszPath)
     600{  TRACE("%x %x %s\n",hDlg, id, pszPath);
     601   return SetDlgItemTextA(hDlg, id, pszPath);
     602}
     603ODINFUNCTION3(BOOL, PathSetDlgItemPathW,
     604              HWND, hDlg,
     605              int, id,
     606              LPCWSTR, pszPath)
     607{  TRACE("%x %x %s\n",hDlg, id, debugstr_w(pszPath));
     608   return SetDlgItemTextW(hDlg, id, pszPath);
     609}
     610ODINFUNCTION3(BOOL, PathSetDlgItemPathAW,
     611              HWND, hDlg,
     612              int, id,
     613              LPCVOID, pszPath)
     614{  if (VERSION_OsIsUnicode())
     615     return PathSetDlgItemPathW(hDlg, id, (LPWSTR)pszPath);
     616   return PathSetDlgItemPathA(hDlg, id, (LPSTR)pszPath);
     617}
     618 
     619/*************************************************************************
     620 * PathQualifyAW [SHELL32.49]
     621 */
     622 
     623ODINFUNCTION1(BOOL, PathQualifyA,
     624              LPCSTR, pszPath)
     625{  FIXME("%s\n",pszPath);
     626   return 0;
     627}
     628ODINFUNCTION1(BOOL, PathQualifyW,
     629              LPCWSTR, pszPath)
     630{  FIXME("%s\n",debugstr_w(pszPath));
     631   return 0;
     632}
     633ODINFUNCTION1(BOOL, PathQualifyAW,
     634              LPCVOID, pszPath)
     635{  if (VERSION_OsIsUnicode())
     636     return PathQualifyW((LPWSTR)pszPath);
     637   return PathQualifyA((LPSTR)pszPath);
     638}
     639 
     640/*************************************************************************
     641 * PathResolve [SHELL32.51]
     642 */
     643ODINFUNCTION3(DWORD, PathResolve,
     644              LPCSTR, s,
     645              DWORD, x2,
     646              DWORD, x3)
     647{
     648   FIXME("(%s,0x%08lx,0x%08lx),stub!\n",s,x2,x3);
     649   return 0;
     650}
     651 
     652/*************************************************************************
     653 * PathGetArgs [SHELL32.52]
     654 *
     655 * NOTES
     656 *     look for next arg in string. handle "quoted" strings
     657 *     returns pointer to argument *AFTER* the space. Or to the \0.
     658 */
     659ODINFUNCTION1(LPCSTR, PathGetArgsA,
     660              LPCSTR, cmdline)
     661{  BOOL  qflag = FALSE;
     662 
     663   TRACE("%s\n",cmdline);
     664 
     665   while (*cmdline)
     666   { if ((*cmdline==' ') && !qflag)
     667       return cmdline+1;
     668     if (*cmdline=='"')
     669       qflag=!qflag;
     670     cmdline++;
     671   }
     672   return cmdline;
     673 
     674}
     675ODINFUNCTION1(LPCWSTR, PathGetArgsW,
     676              LPCWSTR, cmdline)
     677{  BOOL  qflag = FALSE;
     678 
     679   TRACE("%sL\n",debugstr_w(cmdline));
     680 
     681   while (*cmdline)
     682   { if ((*cmdline==' ') && !qflag)
     683       return cmdline+1;
     684     if (*cmdline=='"')
     685       qflag=!qflag;
     686     cmdline++;
     687   }
     688   return cmdline;
     689}
     690ODINFUNCTION1(LPCVOID, PathGetArgsAW,
     691              LPVOID, cmdline)
     692{  if (VERSION_OsIsUnicode())
     693     return PathGetArgsW((LPWSTR)cmdline);
     694   return PathGetArgsA((LPSTR)cmdline);
     695}
     696/*************************************************************************
     697 * PathQuoteSpaces [SHELL32.55]
     698 *
     699 * NOTES
     700 *     basename(char *fn);
     701 */
     702ODINFUNCTION1(LPSTR, PathQuoteSpacesA,
     703              LPCSTR, aptr)
     704{  FIXME("%s\n",aptr);
     705   return 0;
     706 
     707}
     708ODINFUNCTION1(LPWSTR, PathQuoteSpacesW,
     709              LPCWSTR, wptr)
     710{  FIXME("L%s\n",debugstr_w(wptr));
     711   return 0;
     712}
     713ODINFUNCTION1(LPVOID, PathQuoteSpacesAW,
     714              LPCVOID, fn)
     715{  if(VERSION_OsIsUnicode())
     716     return PathQuoteSpacesW((LPWSTR)fn);
     717   return PathQuoteSpacesA((LPSTR)fn);
     718}
     719 
     720 
     721/*************************************************************************
     722 * PathUnquoteSpaces [SHELL32.56]
     723 *
     724 * NOTES
     725 *     unquote string (remove ")
     726 */
     727ODINPROCEDURE1(PathUnquoteSpacesA,
     728               LPSTR, str)
     729{  DWORD      len = lstrlenA(str);
     730   TRACE("%s\n",str);
     731   if (*str!='"')
     732     return;
     733   if (str[len-1]!='"')
     734     return;
     735   str[len-1]='\0';
     736   lstrcpyA(str,str+1);
     737   return;
     738}
     739ODINPROCEDURE1(PathUnquoteSpacesW,
     740               LPWSTR, str)
     741{  DWORD len = lstrlenW(str);
     742 
     743   TRACE("%s\n",debugstr_w(str));
     744 
     745   if (*str!='"')
     746     return;
     747   if (str[len-1]!='"')
     748     return;
     749   str[len-1]='\0';
     750   lstrcpyW(str,str+1);
     751   return;
     752}
     753ODINPROCEDURE1(PathUnquoteSpacesAW,
     754               LPVOID, str)
     755{  if(VERSION_OsIsUnicode())
     756     PathUnquoteSpacesW((LPWSTR)str);
     757   PathUnquoteSpacesA((LPSTR)str);
     758}
     759 
     760 
     761/*************************************************************************
     762 * PathGetDriveNumber32 [SHELL32.57]
     763 *
     764 */
     765ODINFUNCTION1(HRESULT, PathGetDriveNumber,
     766              LPSTR, u)
     767{  FIXME("%s stub\n",debugstr_a(u));
     768   return 0;
     769}
     770 
     771/*************************************************************************
     772 * PathYetAnotherMakeUniqueName [SHELL32.75]
     773 *
     774 * NOTES
     775 *     exported by ordinal
     776 */
     777ODINFUNCTION2(BOOL, PathYetAnotherMakeUniqueNameA,
     778              LPDWORD, x,
     779              LPDWORD, y)
     780{
     781    FIXME("(%p,%p):stub.\n",x,y);
     782    return TRUE;
     783}
     784 
     785/*************************************************************************
     786 * IsLFNDrive [SHELL32.119]
     787 *
     788 * NOTES
     789 *     exported by ordinal Name
     790 */
     791ODINFUNCTION1(BOOL, IsLFNDriveA,
     792              LPCSTR, path)
     793{
     794    DWORD   fnlen;
     795 
     796    if (!GetVolumeInformationA(path,NULL,0,NULL,&fnlen,NULL,NULL,0))
     797   return FALSE;
     798    return fnlen>12;
     799}
     800/*************************************************************************
     801 * PathFindOnPath [SHELL32.145]
     802 */
     803ODINFUNCTION2(BOOL, PathFindOnPathA,
     804              LPSTR, sFile,
     805              LPCSTR, sOtherDirs)
     806{  FIXME("%s %s\n",sFile, sOtherDirs);
     807   return FALSE;
     808}
     809ODINFUNCTION2(BOOL, PathFindOnPathW,
     810              LPWSTR, sFile,
     811              LPCWSTR, sOtherDirs)
     812{  FIXME("%s %s\n",debugstr_w(sFile), debugstr_w(sOtherDirs));
     813   return FALSE;
     814}
     815ODINFUNCTION2(BOOL, PathFindOnPathAW,
     816              LPVOID, sFile,
     817              LPCVOID, sOtherDirs)
     818{  if (VERSION_OsIsUnicode())
     819     return PathFindOnPathW((LPWSTR)sFile, (LPWSTR)sOtherDirs);
     820   return PathFindOnPathA((LPSTR)sFile, (LPSTR)sOtherDirs);
     821}
     822 
     823/*************************************************************************
     824 * PathGetExtension [SHELL32.158]
     825 *
     826 * NOTES
     827 *     exported by ordinal
     828 */
     829ODINFUNCTION3(LPCSTR, PathGetExtensionA,
     830              LPCSTR, path,
     831              DWORD, y,
     832              DWORD, z)
     833{  TRACE("(%s,%08lx,%08lx)\n",path,y,z);
     834   path = PathFindExtensionA(path);
     835   return *path?(path+1):path;
     836}
     837ODINFUNCTION3(LPCWSTR, PathGetExtensionW,
     838              LPCWSTR, path,
     839              DWORD, y,
     840              DWORD, z)
     841{  TRACE("(L%s,%08lx,%08lx)\n",debugstr_w(path),y,z);
     842   path = PathFindExtensionW(path);
     843   return *path?(path+1):path;
     844}
     845ODINFUNCTION3(LPCVOID, PathGetExtensionAW,
     846              LPCVOID, path,
     847              DWORD, y,
     848              DWORD, z)
     849{  if (VERSION_OsIsUnicode())
     850     return PathGetExtensionW((LPWSTR)path,y,z);
     851   return PathGetExtensionA((LPSTR)path,y,z);
     852}
     853 
     854/*************************************************************************
     855 * PathCleanupSpec                                [SHELL32.171]
     856 *
     857 */
     858ODINFUNCTION2(DWORD, PathCleanupSpecA,
     859              LPSTR, x,
     860              LPSTR, y)
     861{
     862   FIXME("%p(%s) %p(%s) stub\n",x,x,y,y);
     863   return TRUE;
     864}
     865 
     866ODINFUNCTION2(DWORD, PathCleanupSpecW,
     867              LPWSTR, x,
     868              LPWSTR, y)
     869{
     870   FIXME("%p(%s) %p(%s) stub\n",x,debugstr_w(x),y,debugstr_w(y));
     871   return TRUE;
     872}
     873 
     874ODINFUNCTION2(DWORD, PathCleanupSpecAW,
     875              LPVOID, x,
     876              LPVOID, y)
     877{
     878   if (VERSION_OsIsUnicode())
     879     return PathCleanupSpecW((LPWSTR)x,(LPWSTR)y);
     880   return PathCleanupSpecA((LPSTR)x,(LPSTR)y);
     881}
     882 
     883/*************************************************************************
     884 * SheGetDirW [SHELL32.281]
     885 *
     886 */
     887ODINFUNCTION2(HRESULT, SheGetDirW,
     888              LPWSTR, u,
     889              LPWSTR, v)
     890{  FIXME("%p %p stub\n",u,v);
     891   return 0;
     892}
     893 
     894/*************************************************************************
     895 * SheChangeDirW [SHELL32.274]
     896 *
     897 */
     898ODINFUNCTION1(HRESULT, SheChangeDirW,
     899              LPWSTR, u)
     900{  FIXME("(%s),stub\n",debugstr_w(u));
     901   return 0;
     902}
     903 
     904/*************************************************************************
     905*  PathProcessCommand                    [SHELL32.653]
     906*/
     907ODINFUNCTION4(HRESULT, PathProcessCommandA,
     908              LPSTR, lpCommand,
     909              LPSTR, v,
     910              DWORD, w,
     911              DWORD, x)
     912{
     913   FIXME("%p(%s) %p 0x%04lx 0x%04lx stub\n",
     914   lpCommand, lpCommand, v, w,x );
     915   return 0;
     916}
     917 
     918ODINFUNCTION4(HRESULT, PathProcessCommandW,
     919              LPWSTR, lpCommand,
     920              LPSTR, v,
     921              DWORD, w,
     922              DWORD, x)
     923{
     924   FIXME("%p(%s) %p 0x%04lx 0x%04lx stub\n",
     925   lpCommand, debugstr_w(lpCommand), v, w,x );
     926   return 0;
     927}
     928 
     929ODINFUNCTION4(HRESULT, PathProcessCommandAW,
     930              LPVOID, lpCommand,
     931              LPSTR, v,
     932              DWORD, w,
     933              DWORD, x)
     934{
     935   if (VERSION_OsIsUnicode())
     936     return PathProcessCommandW((LPWSTR)lpCommand, v, w, x);
     937   return PathProcessCommandA((LPSTR)lpCommand, v, w, x);
     938}
     939 
     940/*************************************************************************
     941 * SHGetSpecialFolderPath [SHELL32.175]
     942 *
     943 * converts csidl to path
     944 *
     945 */
     946 
     947static char * szSHFolders = "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders";
     948 
     949ODINFUNCTION4(BOOL, SHGetSpecialFolderPathA,
     950              HWND, hwndOwner,
     951              LPSTR, szPath,
     952              DWORD, csidl,
     953              BOOL, bCreate)
     954{
     955   CHAR  szValueName[MAX_PATH], szDefaultPath[MAX_PATH];
     956   HKEY  hRootKey, hKey;
     957   BOOL  bRelative = TRUE;
     958   DWORD dwType, dwDisp, dwPathLen = MAX_PATH;
     959 
     960   TRACE("0x%04x,%p,csidl=%lu,0x%04x\n", hwndOwner,szPath,csidl,bCreate);
     961 
     962   /* build default values */
     963   switch(csidl)
     964   {
     965     case CSIDL_APPDATA:
     966       hRootKey = HKEY_CURRENT_USER;
     967       strcpy (szValueName, "AppData");
     968       strcpy (szDefaultPath, "AppData");
     969       break;
     970 
     971     case CSIDL_COOKIES:
     972       hRootKey = HKEY_CURRENT_USER;
     973       strcpy (szValueName, "Cookies");
     974       strcpy(szDefaultPath, "Cookies");
     975       break;
     976 
     977     case CSIDL_DESKTOPDIRECTORY:
     978       hRootKey = HKEY_CURRENT_USER;
     979       strcpy(szValueName, "Desktop");
     980       strcpy(szDefaultPath, "Desktop");
     981       break;
     982 
     983     case CSIDL_COMMON_DESKTOPDIRECTORY:
     984       hRootKey = HKEY_LOCAL_MACHINE;
     985       strcpy(szValueName, "Common Desktop");
     986       strcpy(szDefaultPath, "Desktop");
     987       break;
     988 
     989     case CSIDL_FAVORITES:
     990       hRootKey = HKEY_CURRENT_USER;
     991       strcpy(szValueName, "Favorites");
     992       strcpy(szDefaultPath, "Favorites");
     993       break;
     994 
     995     case CSIDL_FONTS:
     996       hRootKey = HKEY_CURRENT_USER;
     997       strcpy(szValueName, "Fonts");
     998       strcpy(szDefaultPath, "Fonts");
     999       break;
     1000 
     1001     case CSIDL_HISTORY:
     1002       hRootKey = HKEY_CURRENT_USER;
     1003       strcpy(szValueName, "History");
     1004       strcpy(szDefaultPath, "History");
     1005       break;
     1006 
     1007     case CSIDL_NETHOOD:
     1008       hRootKey = HKEY_CURRENT_USER;
     1009       strcpy(szValueName, "NetHood");
     1010       strcpy(szDefaultPath, "NetHood");
     1011       break;
     1012 
     1013     case CSIDL_INTERNET_CACHE:
     1014       hRootKey = HKEY_CURRENT_USER;
     1015       strcpy(szValueName, "Cache");
     1016       strcpy(szDefaultPath, "Temporary Internet Files");
     1017       break;
     1018 
     1019     case CSIDL_PERSONAL:
     1020       hRootKey = HKEY_CURRENT_USER;
     1021       strcpy(szValueName, "Personal");
     1022       strcpy(szDefaultPath, "My Own Files");
     1023       bRelative = FALSE;
     1024       break;
     1025 
     1026     case CSIDL_PRINTHOOD:
     1027       hRootKey = HKEY_CURRENT_USER;
     1028       strcpy(szValueName, "PrintHood");
     1029       strcpy(szDefaultPath, "PrintHood");
     1030       break;
     1031 
     1032     case CSIDL_PROGRAMS:
     1033       hRootKey = HKEY_CURRENT_USER;
     1034       strcpy(szValueName, "Programs");
     1035       strcpy(szDefaultPath, "StatrMenu\\Programs");
     1036       break;
     1037 
     1038     case CSIDL_COMMON_PROGRAMS:
     1039       hRootKey = HKEY_LOCAL_MACHINE;
     1040       strcpy(szValueName, "Common Programs");
     1041       strcpy(szDefaultPath, "");
     1042       break;
     1043 
     1044     case CSIDL_RECENT:
     1045       hRootKey = HKEY_CURRENT_USER;
     1046       strcpy(szValueName, "Recent");
     1047       strcpy(szDefaultPath, "Recent");
     1048       break;
     1049 
     1050     case CSIDL_SENDTO:
     1051       hRootKey = HKEY_CURRENT_USER;
     1052       strcpy(szValueName, "SendTo");
     1053       strcpy(szDefaultPath, "SendTo");
     1054       break;
     1055 
     1056     case CSIDL_STARTMENU:
     1057       hRootKey = HKEY_CURRENT_USER;
     1058       strcpy(szValueName, "StartMenu");
     1059       strcpy(szDefaultPath, "StartMenu");
     1060       break;
     1061 
     1062     case CSIDL_COMMON_STARTMENU:
     1063       hRootKey = HKEY_LOCAL_MACHINE;
     1064       strcpy(szValueName, "Common StartMenu");
     1065       strcpy(szDefaultPath, "StartMenu");
     1066       break;
     1067 
     1068     case CSIDL_STARTUP:
     1069       hRootKey = HKEY_CURRENT_USER;
     1070       strcpy(szValueName, "Startup");
     1071       strcpy(szDefaultPath, "StartMenu\\Programs\\Startup");
     1072       break;
     1073 
     1074     case CSIDL_COMMON_STARTUP:
     1075       hRootKey = HKEY_LOCAL_MACHINE;
     1076       strcpy(szValueName, "Common Startup");
     1077       strcpy(szDefaultPath, "StartMenu\\Programs\\Startup");
     1078       break;
     1079 
     1080     case CSIDL_TEMPLATES:
     1081       hRootKey = HKEY_CURRENT_USER;
     1082       strcpy(szValueName, "Templates");
     1083       strcpy(szDefaultPath, "ShellNew");
     1084       break;
     1085 
     1086     default:
     1087       ERR("folder unknown or not allowed\n");
     1088       return FALSE;
     1089   }
     1090 
     1091   if (RegCreateKeyExA(hRootKey,szSHFolders,0,NULL,REG_OPTION_NON_VOLATILE,KEY_WRITE,NULL,&hKey,&dwDisp))
     1092   {
     1093     return FALSE;
     1094   }
     1095 
     1096   if (RegQueryValueExA(hKey,szValueName,NULL,&dwType,(LPBYTE)szPath,&dwPathLen))
     1097   {
     1098     /* value not existing */
     1099     if (bRelative)
     1100     {
     1101       GetWindowsDirectoryA(szPath, MAX_PATH);
     1102       PathAddBackslashA(szPath);
     1103       strcat(szPath, szDefaultPath);
     1104     }
     1105     else
     1106     {
     1107       strcpy(szPath, szDefaultPath);
     1108     }
     1109     if (bCreate)
     1110     {
     1111       CreateDirectoryA(szPath,NULL);
     1112     }
     1113     RegSetValueExA(hKey,szValueName,0,REG_SZ,(LPBYTE)szPath,strlen(szPath)+1);
     1114   }
     1115   RegCloseKey(hKey);
     1116 
     1117   return TRUE;
     1118}
     1119ODINFUNCTION4(BOOL, SHGetSpecialFolderPathW,
     1120              HWND, hwndOwner,
     1121              LPWSTR, szPath,
     1122              DWORD, csidl,
     1123              BOOL, bCreate)
     1124{
     1125   char szTemp[MAX_PATH];
     1126 
     1127   if (SHGetSpecialFolderPathA(hwndOwner, szTemp, csidl, bCreate))
     1128   {
     1129     lstrcpynAtoW(szPath, szTemp, MAX_PATH);
     1130   }
     1131 
     1132   TRACE("0x%04x,%p,csidl=%lu,0x%04x\n", hwndOwner,szPath,csidl,bCreate);
     1133 
     1134   return TRUE;
     1135}
     1136ODINFUNCTION4(BOOL, SHGetSpecialFolderPathAW,
     1137              HWND, hwndOwner,
     1138              LPVOID, szPath,
     1139              DWORD, csidl,
     1140              BOOL, bCreate)
     1141{
     1142   if (VERSION_OsIsUnicode())
     1143     return SHGetSpecialFolderPathW (hwndOwner, (LPWSTR)szPath, csidl, bCreate);
     1144   return SHGetSpecialFolderPathA (hwndOwner, (LPSTR)szPath, csidl, bCreate);
     1145}
    131146
    14 #define ICOM_CINTERFACE 1
    15 #define CINTERFACE 1
    16 
    17 #include "debugtools.h"
    18 #include "winnls.h"
    19 #include "winversion.h"
    20 #include "winreg.h"
    21 #include "crtdll.h"
    22 
    23 #include "shlobj.h"
    24 #include "shell32_main.h"
    25 
    26 #include <heapstring.h>
    27 #include <misc.h>
    28 
    29 DEFAULT_DEBUG_CHANNEL(shell)
    30 
    31 /*************************************************************************
    32  * PathIsRoot [SHELL32.29]
    33  */
    34 BOOL WINAPI PathIsRootA(LPCSTR x)
    35 {       TRACE("%s\n",x);
    36         if (*(x+1)==':' && *(x+2)=='\\')                /* "X:\" */
    37           return 1;
    38         if (*x=='\\')           /* "\" */
    39           return 0;
    40         if (x[0]=='\\' && x[1]=='\\')           /* UNC "\\<xx>\" */
    41         { int   foundbackslash = 0;
    42           x=x+2;
    43           while (*x)
    44           { if (*x++=='\\')
    45               foundbackslash++;
    46           }
    47           if (foundbackslash<=1)        /* max 1 \ more ... */
    48             return 1;
    49         }
    50         return 0;
    51 }
    52 BOOL WINAPI PathIsRootW(LPCWSTR x)
    53 {       TRACE("%s\n",debugstr_w(x));
    54         if (*(x+1)==':' && *(x+2)=='\\')                /* "X:\" */
    55           return 1;
    56         if (*x == (WCHAR) '\\')         /* "\" */
    57           return 0;
    58         if (x[0]==(WCHAR)'\\' && x[1]==(WCHAR)'\\')     /* UNC "\\<xx>\" */
    59         { int   foundbackslash = 0;
    60           x=x+2;
    61           while (*x)
    62           { if (*x++==(WCHAR)'\\')
    63               foundbackslash++;
    64           }
    65           if (foundbackslash<=1)        /* max 1 \ more ... */
    66             return 1;
    67         }
    68         return 0;
    69 }
    70 BOOL WINAPI PathIsRootAW(LPCVOID x)
    71 {       if (VERSION_OsIsUnicode())
    72           return PathIsRootW((LPWSTR)x);
    73         return PathIsRootA((LPSTR)x);
    74 
    75 }
    76 /*************************************************************************
    77  * PathBuildRoot [SHELL32.30]
    78  */
    79 LPSTR WINAPI PathBuildRootA(LPSTR root,BYTE drive) {
    80   TRACE("%p %i\n",root, drive);
    81         strcpy(root,"A:\\");
    82         root[0]+=drive;
    83         return root;
    84 }
    85 
    86 /*************************************************************************
    87  * PathFindExtension [SHELL32.31]
    88  *
    89  * NOTES
    90  *     returns pointer to last . in last pathcomponent or at \0.
    91  */
    92 LPCSTR WINAPI PathFindExtensionA(LPCSTR path)
    93 {       LPCSTR   lastpoint = NULL;
    94         TRACE("%p %s\n",path,path);
    95         while (*path)
    96         { if (*path=='\\'||*path==' ')
    97             lastpoint=NULL;
    98           if (*path=='.')
    99             lastpoint=path;
    100           path++;
    101         }
    102         return lastpoint?lastpoint:path;
    103 }
    104 LPCWSTR WINAPI PathFindExtensionW(LPCWSTR path)
    105 {       LPCWSTR   lastpoint = NULL;
    106         TRACE("%p L%s\n",path,debugstr_w(path));
    107         while (*path)
    108         { if (*path==(WCHAR)'\\'||*path==(WCHAR)' ')
    109             lastpoint=NULL;
    110           if (*path==(WCHAR)'.')
    111             lastpoint=path;
    112           path++;
    113         }
    114         return lastpoint?lastpoint:path;
    115 }
    116 LPCVOID WINAPI PathFindExtensionAW(LPCVOID path)
    117 {       if (VERSION_OsIsUnicode())
    118           return PathFindExtensionW((LPWSTR)path);
    119         return PathFindExtensionA((LPSTR)path);
    120 
    121 }
    122 
    123 /*************************************************************************
    124  * PathAddBackslash [SHELL32.32]
    125  *
    126  * NOTES
    127  *     append \ if there is none
    128  */
    129 LPSTR WINAPI PathAddBackslashA(LPSTR path)
    130 {       int len;
    131         TRACE("%p->%s\n",path,path);
    132 
    133         len = strlen(path);
    134         if (len && path[len-1]!='\\')
    135         { path[len]  = '\\';
    136           path[len+1]= 0x00;
    137           return path+len+1;
    138         }
    139         return path+len;
    140 }
    141 LPWSTR WINAPI PathAddBackslashW(LPWSTR path)
    142 {       int len;
    143         TRACE("%p->%s\n",path,debugstr_w(path));
    144 
    145         len = lstrlenW(path);
    146         if (len && path[len-1]!=(WCHAR)'\\')
    147         { path[len]  = (WCHAR)'\\';
    148           path[len+1]= 0x00;
    149           return path+len+1;
    150         }
    151         return path+len;
    152 }
    153 LPVOID WINAPI PathAddBackslashAW(LPVOID path)
    154 {       if(VERSION_OsIsUnicode())
    155           return PathAddBackslashW((LPWSTR)path);
    156         return PathAddBackslashA((LPSTR)path);
    157 }
    158 
    159 /*************************************************************************
    160  * PathRemoveBlanks [SHELL32.33]
    161  *
    162  * NOTES
    163  *     remove spaces from beginning and end of passed string
    164  */
    165 LPSTR WINAPI PathRemoveBlanksA(LPSTR str)
    166 {       LPSTR x = str;
    167         TRACE("%s\n",str);
    168         while (*x==' ') x++;
    169         if (x!=str)
    170           strcpy(str,x);
    171         if (!*str)
    172           return str;
    173         x=str+strlen(str)-1;
    174         while (*x==' ')
    175           x--;
    176         if (*x==' ')
    177           *x='\0';
    178         return x;
    179 }
    180 LPWSTR WINAPI PathRemoveBlanksW(LPWSTR str)
    181 {       LPWSTR x = str;
    182         TRACE("%s\n",debugstr_w(str));
    183         while (*x==' ') x++;
    184         if (x!=str)
    185           lstrcpyW(str,x);
    186         if (!*str)
    187           return str;
    188         x=str+lstrlenW(str)-1;
    189         while (*x==' ')
    190           x--;
    191         if (*x==' ')
    192           *x='\0';
    193         return x;
    194 }
    195 LPVOID WINAPI PathRemoveBlanksAW(LPVOID str)
    196 {       if(VERSION_OsIsUnicode())
    197           return PathRemoveBlanksW((LPWSTR)str);
    198         return PathRemoveBlanksA((LPSTR)str);
    199 }
    200 
    201 
    202 
    203 /*************************************************************************
    204  * PathFindFilename [SHELL32.34]
    205  *
    206  * NOTES
    207  *     basename(char *fn);
    208  */
    209 LPCSTR WINAPI PathFindFilenameA(LPCSTR aptr)
    210 {       LPCSTR aslash;
    211         aslash = aptr;
    212 
    213         TRACE("%s\n",aslash);
    214         while (aptr[0])
    215         { if (((aptr[0]=='\\') || (aptr[0]==':')) && aptr[1] && aptr[1]!='\\')
    216               aslash = aptr+1;
    217           aptr++;
    218         }
    219         return aslash;
    220 
    221 }
    222 LPCWSTR WINAPI PathFindFilenameW(LPCWSTR wptr)
    223 {       LPCWSTR wslash;
    224         wslash = wptr;
    225 
    226         TRACE("L%s\n",debugstr_w(wslash));
    227         while (wptr[0])
    228         { if (((wptr[0]=='\\') || (wptr[0]==':')) && wptr[1] && wptr[1]!='\\')
    229             wslash = wptr+1;
    230           wptr++;
    231         }
    232         return wslash; 
    233 }
    234 LPCVOID WINAPI PathFindFilenameAW(LPCVOID fn)
    235 {
    236         if(VERSION_OsIsUnicode())
    237           return PathFindFilenameW((LPWSTR)fn);
    238         return PathFindFilenameA((LPSTR)fn);
    239 }
    240 
    241 /*************************************************************************
    242  * PathRemoveFileSpec [SHELL32.35]
    243  *
    244  * NOTES
    245  *     bool getpath(char *pathname); truncates passed argument to a valid path
    246  *     returns if the string was modified or not.
    247  *     "\foo\xx\foo"-> "\foo\xx"
    248  *     "\" -> "\"
    249  *     "a:\foo" -> "a:\"
    250  */
    251 DWORD WINAPI PathRemoveFileSpecA(LPSTR fn) {
    252         LPSTR   x,cutplace;
    253   TRACE("%s\n",fn);
    254         if (!fn[0])
    255                 return 0;
    256         x=fn;
    257         cutplace = fn;
    258         while (*x) {
    259                 if (*x=='\\') {
    260                         cutplace=x++;
    261                         continue;
    262                 }
    263                 if (*x==':') {
    264                         x++;
    265                         if (*x=='\\')
    266                                 cutplace=++x;
    267                         continue; /* already x++ed */
    268                 }
    269                 x++;
    270         }
    271         if (!*cutplace)
    272                 return 0;
    273         if (cutplace==fn) {
    274                 if (fn[0]=='\\') {
    275                         if (!fn[1])
    276                                 return 0;
    277                         fn[0]='\0';
    278                         return 1;
    279                 }
    280         }
    281         *cutplace='\0';
    282         return 1;
    283 }
    284 
    285 /*************************************************************************
    286  * PathAppend [SHELL32.36]
    287  *
    288  * NOTES
    289  *     concat_paths(char*target,const char*add);
    290  *     concats "target\\add" and writes them to target
    291  */
    292 LPSTR WINAPI PathAppendA(LPSTR x1,LPSTR x2) {
    293   TRACE("%s %s\n",x1,x2);
    294   while (x2[0]=='\\') x2++;
    295   return PathCombineA(x1,x1,x2);
    296 }
    297 
    298 /*************************************************************************
    299  * PathCombine [SHELL32.37]
    300  *
    301  * NOTES
    302  *  if lpszFile='.' skip it
    303  *  szDest can be equal to lpszFile. Thats why we use sTemp
    304  */
    305 LPSTR WINAPI PathCombineA(LPSTR szDest, LPCSTR lpszDir, LPCSTR lpszFile)
    306 {       char sTemp[MAX_PATH];
    307         TRACE("%p %p->%s %p->%s\n",szDest, lpszDir, lpszDir, lpszFile, lpszFile);
    308        
    309        
    310         if (!lpszFile || !lpszFile[0] || (lpszFile[0]=='.' && !lpszFile[1]) )
    311         { strcpy(szDest,lpszDir);
    312           return szDest;
    313         }
    314 
    315         /*  if lpszFile is a complete path don't care about lpszDir */
    316         if (PathIsRootA(lpszFile))
    317         { strcpy(szDest,lpszFile);
    318         }
    319         else
    320         { strcpy(sTemp,lpszDir);
    321           PathAddBackslashA(sTemp);
    322           strcat(sTemp,lpszFile);
    323           strcpy(szDest,sTemp);
    324         }
    325         return szDest;
    326 }
    327 LPWSTR WINAPI PathCombineW(LPWSTR szDest, LPCWSTR lpszDir, LPCWSTR lpszFile)
    328 {       WCHAR sTemp[MAX_PATH];
    329         TRACE("%p %p->%s %p->%s\n",szDest, lpszDir, debugstr_w(lpszDir),
    330                          lpszFile, debugstr_w(lpszFile));
    331        
    332        
    333         if (!lpszFile || !lpszFile[0] || (lpszFile[0]==(WCHAR)'.' && !lpszFile[1]) )
    334         { lstrcpyW(szDest,lpszDir);
    335           return szDest;
    336         }
    337 
    338         /*  if lpszFile is a complete path don't care about lpszDir */
    339         if (PathIsRootW(lpszFile))
    340         { lstrcpyW(szDest,lpszFile);
    341         }
    342         else
    343         { lstrcpyW(sTemp,lpszDir);
    344           PathAddBackslashW(sTemp);
    345           lstrcatW(sTemp,lpszFile);
    346           lstrcpyW(szDest,sTemp);
    347         }
    348         return szDest;
    349 }
    350 LPVOID WINAPI PathCombineAW(LPVOID szDest, LPCVOID lpszDir, LPCVOID lpszFile)
    351 {       if (VERSION_OsIsUnicode())
    352           return PathCombineW( (LPWSTR)szDest, (LPWSTR)lpszDir, (LPWSTR)lpszFile );
    353         return PathCombineA( (LPSTR)szDest, (LPSTR)lpszDir, (LPSTR)lpszFile );
    354 }
    355 
    356 /*************************************************************************
    357  * PathIsUNC [SHELL32.39]
    358  *
    359  * NOTES
    360  *     PathIsUNC(char*path);
    361  */
    362 BOOL WINAPI PathIsUNCA(LPCSTR path)
    363 {       TRACE("%s\n",path);
    364 
    365         if ((path[0]=='\\') && (path[1]=='\\'))
    366           return TRUE;
    367         return FALSE;
    368 }
    369 BOOL WINAPI PathIsUNCW(LPCWSTR path)
    370 {       TRACE("%s\n",debugstr_w(path));
    371 
    372         if ((path[0]=='\\') && (path[1]=='\\'))
    373           return TRUE;
    374         return FALSE;
    375 }
    376 BOOL WINAPI PathIsUNCAW (LPCVOID path)
    377 {       if (VERSION_OsIsUnicode())
    378           return PathIsUNCW( (LPWSTR)path );
    379         return PathIsUNCA( (LPSTR)path );
    380 }
    381 /*************************************************************************
    382  *  PathIsRelativ [SHELL32.40]
    383  *
    384  */
    385 BOOL WINAPI PathIsRelativeA (LPCSTR path)
    386 {       TRACE("path=%s\n",path);
    387 
    388         if (path && (path[0]!='\\' && path[1]==':'))
    389           return TRUE;
    390         return FALSE;
    391 }
    392 BOOL WINAPI PathIsRelativeW (LPCWSTR path)
    393 {       TRACE("path=%s\n",debugstr_w(path));
    394 
    395         if (path && (path[0]!='\\' && path[1]==':'))
    396           return TRUE;
    397         return FALSE;
    398 }
    399 BOOL WINAPI PathIsRelativeAW (LPCVOID path)
    400 {       if (VERSION_OsIsUnicode())
    401           return PathIsRelativeW( (LPWSTR)path );
    402         return PathIsRelativeA( (LPSTR)path );
    403 }
    404 /*************************************************************************
    405  *  PathIsExe [SHELL32.43]
    406  *
    407  */
    408 BOOL WINAPI PathIsExeA (LPCSTR path)
    409 {       FIXME("path=%s\n",path);
    410         return FALSE;
    411 }
    412 BOOL WINAPI PathIsExeW (LPCWSTR path)
    413 {       FIXME("path=%s\n",debugstr_w(path));
    414         return FALSE;
    415 }
    416 BOOL WINAPI PathIsExeAW (LPCVOID path)
    417 {       if (VERSION_OsIsUnicode())
    418           return PathIsExeW ((LPWSTR)path);
    419         return PathIsExeA((LPSTR)path);
    420 }
    421 
    422 /*************************************************************************
    423  * PathFileExists [SHELL32.45]
    424  *
    425  * NOTES
    426  *     file_exists(char *fn);
    427  */
    428 BOOL WINAPI PathFileExistsA(LPSTR fn) {
    429   TRACE("%s\n",fn);
    430    if (GetFileAttributesA(fn)==-1)
    431         return FALSE;
    432     else
    433         return TRUE;
    434 }
    435 /*************************************************************************
    436  * PathMatchSingleMask
    437  *
    438  * NOTES
    439  *     internal (used by PathMatchSpec)
    440  */
    441 static BOOL PathMatchSingleMaskA(LPCSTR name, LPCSTR mask)
    442 {
    443   while (*name && *mask && *mask!=';') {
    444     if (*mask=='*') {
    445       do {
    446         if (PathMatchSingleMaskA(name,mask+1)) return 1;  /* try substrings */
    447       } while (*name++);
    448       return 0;
    449     }
    450     if (toupper(*mask)!=toupper(*name) && *mask!='?') return 0;
    451     name++;
    452     mask++;
    453   }
    454   if (!*name) {
    455     while (*mask=='*') mask++;
    456     if (!*mask || *mask==';') return 1;
    457   }
    458   return 0;
    459 }
    460 static BOOL PathMatchSingleMaskW(LPCWSTR name, LPCWSTR mask)
    461 {
    462   while (*name && *mask && *mask!=';') {
    463     if (*mask=='*') {
    464       do {
    465         if (PathMatchSingleMaskW(name,mask+1)) return 1;  /* try substrings */
    466       } while (*name++);
    467       return 0;
    468     }
    469     if (towupper(*mask)!=towupper(*name) && *mask!='?') return 0;
    470     name++;
    471     mask++;
    472   }
    473   if (!*name) {
    474     while (*mask=='*') mask++;
    475     if (!*mask || *mask==';') return 1;
    476   }
    477   return 0;
    478 }
    479 /*************************************************************************
    480  * PathMatchSpec [SHELL32.46]
    481  *
    482  * NOTES
    483  *     used from COMDLG32
    484  */
    485 BOOL WINAPI PathMatchSpecA(LPCSTR name, LPCSTR mask)
    486 {
    487   TRACE("%s %s\n",name,mask);
    488 
    489   if (!lstrcmpA( mask, "*.*" )) return 1;   /* we don't require a period */
    490 
    491   while (*mask) {
    492     if (PathMatchSingleMaskA(name,mask)) return 1;    /* helper function */
    493     while (*mask && *mask!=';') mask++;
    494     if (*mask==';') {
    495       mask++;
    496       while (*mask==' ') mask++;      /*  masks may be separated by "; " */
    497           }
    498         }
    499   return 0;
    500 }
    501 BOOL WINAPI PathMatchSpecW(LPCWSTR name, LPCWSTR mask)
    502 {       WCHAR stemp[4];
    503   TRACE("%ls %ls\n",name,mask);
    504         lstrcpyAtoW(stemp,"*.*");       
    505   if (!lstrcmpW( mask, stemp )) return 1;   /* we don't require a period */
    506 
    507   while (*mask) {
    508     if (PathMatchSingleMaskW(name,mask)) return 1;    /* helper function */
    509     while (*mask && *mask!=';') mask++;
    510     if (*mask==';') {
    511       mask++;
    512       while (*mask==' ') mask++;       /* masks may be separated by "; " */
    513           }
    514         }
    515   return 0;
    516 }
    517 BOOL WINAPI PathMatchSpecAW(LPVOID name, LPVOID mask)
    518 {       if (VERSION_OsIsUnicode())
    519           return PathMatchSpecW( (LPWSTR)name, (LPWSTR)mask );
    520         return PathMatchSpecA( (LPSTR)name, (LPSTR)mask );
    521 }
    522 /*************************************************************************
    523  * PathSetDlgItemPathAW [SHELL32.48]
    524  * NOTES
    525  *  use PathCompactPath to make sure, the path fits into the control
    526  */
    527 
    528 BOOL WINAPI PathSetDlgItemPathA(HWND hDlg, int id, LPCSTR pszPath)
    529 {       TRACE("%x %x %s\n",hDlg, id, pszPath);
    530         return SetDlgItemTextA(hDlg, id, pszPath);
    531 }
    532 BOOL WINAPI PathSetDlgItemPathW(HWND hDlg, int id, LPCWSTR pszPath)
    533 {       TRACE("%x %x %s\n",hDlg, id, debugstr_w(pszPath));
    534         return SetDlgItemTextW(hDlg, id, pszPath);
    535 }
    536 BOOL WINAPI PathSetDlgItemPathAW(HWND hDlg, int id, LPCVOID pszPath)
    537 {       if (VERSION_OsIsUnicode())
    538           return PathSetDlgItemPathW(hDlg, id, (LPWSTR)pszPath);
    539         return PathSetDlgItemPathA(hDlg, id, (LPSTR)pszPath);
    540 }
    541 
    542 /*************************************************************************
    543  * PathQualifyAW [SHELL32.49]
    544  */
    545 
    546 BOOL WINAPI PathQualifyA(LPCSTR pszPath)
    547 {       FIXME("%s\n",pszPath);
    548         return 0;
    549 }
    550 BOOL WINAPI PathQualifyW(LPCWSTR pszPath)
    551 {       FIXME("%s\n",debugstr_w(pszPath));
    552         return 0;
    553 }
    554 BOOL WINAPI PathQualifyAW(LPCVOID pszPath)
    555 {       if (VERSION_OsIsUnicode())
    556           return PathQualifyW((LPWSTR)pszPath);
    557         return PathQualifyA((LPSTR)pszPath);
    558 }
    559 
    560 /*************************************************************************
    561  * PathResolve [SHELL32.51]
    562  */
    563 DWORD WINAPI PathResolve(LPCSTR s,DWORD x2,DWORD x3) {
    564         FIXME("(%s,0x%08lx,0x%08lx),stub!\n",s,x2,x3);
    565         return 0;
    566 }
    567 
    568 /*************************************************************************
    569  * PathGetArgs [SHELL32.52]
    570  *
    571  * NOTES
    572  *     look for next arg in string. handle "quoted" strings
    573  *     returns pointer to argument *AFTER* the space. Or to the \0.
    574  */
    575 LPCSTR WINAPI PathGetArgsA(LPCSTR cmdline)
    576 {       BOOL    qflag = FALSE;
    577 
    578         TRACE("%s\n",cmdline);
    579 
    580         while (*cmdline)
    581         { if ((*cmdline==' ') && !qflag)
    582             return cmdline+1;
    583           if (*cmdline=='"')
    584             qflag=!qflag;
    585           cmdline++;
    586         }
    587         return cmdline;
    588 
    589 }
    590 LPCWSTR WINAPI PathGetArgsW(LPCWSTR cmdline)
    591 {       BOOL    qflag = FALSE;
    592 
    593         TRACE("%sL\n",debugstr_w(cmdline));
    594 
    595         while (*cmdline)
    596         { if ((*cmdline==' ') && !qflag)
    597             return cmdline+1;
    598           if (*cmdline=='"')
    599             qflag=!qflag;
    600           cmdline++;
    601         }
    602         return cmdline;
    603 }
    604 LPCVOID WINAPI PathGetArgsAW(LPVOID cmdline)
    605 {       if (VERSION_OsIsUnicode())
    606           return PathGetArgsW((LPWSTR)cmdline);
    607         return PathGetArgsA((LPSTR)cmdline);
    608 }
    609 /*************************************************************************
    610  * PathQuoteSpaces [SHELL32.55]
    611  *
    612  * NOTES
    613  *     basename(char *fn);
    614  */
    615 LPSTR WINAPI PathQuoteSpacesA(LPCSTR aptr)
    616 {       FIXME("%s\n",aptr);
    617         return 0;
    618 
    619 }
    620 LPWSTR WINAPI PathQuoteSpacesW(LPCWSTR wptr)
    621 {       FIXME("L%s\n",debugstr_w(wptr));
    622         return 0;       
    623 }
    624 LPVOID WINAPI PathQuoteSpacesAW (LPCVOID fn)
    625 {       if(VERSION_OsIsUnicode())
    626           return PathQuoteSpacesW((LPWSTR)fn);
    627         return PathQuoteSpacesA((LPSTR)fn);
    628 }
    629 
    630 
    631 /*************************************************************************
    632  * PathUnquoteSpaces [SHELL32.56]
    633  *
    634  * NOTES
    635  *     unquote string (remove ")
    636  */
    637 VOID WINAPI PathUnquoteSpacesA(LPSTR str)
    638 {       DWORD      len = lstrlenA(str);
    639         TRACE("%s\n",str);
    640         if (*str!='"')
    641           return;
    642         if (str[len-1]!='"')
    643           return;
    644         str[len-1]='\0';
    645         lstrcpyA(str,str+1);
    646         return;
    647 }
    648 VOID WINAPI PathUnquoteSpacesW(LPWSTR str)
    649 {       DWORD len = lstrlenW(str);
    650 
    651         TRACE("%s\n",debugstr_w(str));
    652 
    653         if (*str!='"')
    654           return;
    655         if (str[len-1]!='"')
    656           return;
    657         str[len-1]='\0';
    658         lstrcpyW(str,str+1);
    659         return;
    660 }
    661 VOID WINAPI PathUnquoteSpacesAW(LPVOID str)
    662 {       if(VERSION_OsIsUnicode())
    663           PathUnquoteSpacesW((LPWSTR)str);
    664         PathUnquoteSpacesA((LPSTR)str);
    665 }
    666 
    667 
    668 /*************************************************************************
    669  * PathGetDriveNumber32 [SHELL32.57]
    670  *
    671  */
    672 HRESULT WINAPI PathGetDriveNumber(LPSTR u)
    673 {       FIXME("%s stub\n",debugstr_a(u));
    674         return 0;
    675 }
    676 
    677 /*************************************************************************
    678  * PathYetAnotherMakeUniqueName [SHELL32.75]
    679  *
    680  * NOTES
    681  *     exported by ordinal
    682  */
    683 BOOL WINAPI PathYetAnotherMakeUniqueNameA(LPDWORD x,LPDWORD y) {
    684     FIXME("(%p,%p):stub.\n",x,y);
    685     return TRUE;
    686 }
    687 
    688 /*************************************************************************
    689  * IsLFNDrive [SHELL32.119]
    690  *
    691  * NOTES
    692  *     exported by ordinal Name
    693  */
    694 BOOL WINAPI IsLFNDriveA(LPCSTR path) {
    695     DWORD       fnlen;
    696 
    697     if (!GetVolumeInformationA(path,NULL,0,NULL,&fnlen,NULL,NULL,0))
    698         return FALSE;
    699     return fnlen>12;
    700 }
    701 /*************************************************************************
    702  * PathFindOnPath [SHELL32.145]
    703  */
    704 BOOL WINAPI PathFindOnPathA(LPSTR sFile, LPCSTR sOtherDirs)
    705 {       FIXME("%s %s\n",sFile, sOtherDirs);
    706         return FALSE;
    707 }
    708 BOOL WINAPI PathFindOnPathW(LPWSTR sFile, LPCWSTR sOtherDirs)
    709 {       FIXME("%s %s\n",debugstr_w(sFile), debugstr_w(sOtherDirs));
    710         return FALSE;
    711 }
    712 BOOL WINAPI PathFindOnPathAW(LPVOID sFile, LPCVOID sOtherDirs)
    713 {       if (VERSION_OsIsUnicode())
    714           return PathFindOnPathW((LPWSTR)sFile, (LPWSTR)sOtherDirs);
    715         return PathFindOnPathA((LPSTR)sFile, (LPSTR)sOtherDirs);
    716 }
    717 
    718 /*************************************************************************
    719  * PathGetExtension [SHELL32.158]
    720  *
    721  * NOTES
    722  *     exported by ordinal
    723  */
    724 LPCSTR WINAPI PathGetExtensionA(LPCSTR path,DWORD y,DWORD z)
    725 {       TRACE("(%s,%08lx,%08lx)\n",path,y,z);
    726         path = PathFindExtensionA(path);
    727         return *path?(path+1):path;
    728 }
    729 LPCWSTR WINAPI PathGetExtensionW(LPCWSTR path,DWORD y,DWORD z)
    730 {       TRACE("(L%s,%08lx,%08lx)\n",debugstr_w(path),y,z);
    731         path = PathFindExtensionW(path);
    732         return *path?(path+1):path;
    733 }
    734 LPCVOID WINAPI PathGetExtensionAW(LPCVOID path,DWORD y,DWORD z)
    735 {       if (VERSION_OsIsUnicode())
    736           return PathGetExtensionW((LPWSTR)path,y,z);
    737         return PathGetExtensionA((LPSTR)path,y,z);
    738 }
    739 
    740 /*************************************************************************
    741  * PathCleanupSpec                              [SHELL32.171]
    742  *
    743  */
    744 DWORD WINAPI PathCleanupSpecA(LPSTR x, LPSTR y)
    745 {
    746         FIXME("%p(%s) %p(%s) stub\n",x,x,y,y);
    747         return TRUE;
    748 }
    749 
    750 DWORD WINAPI PathCleanupSpecW(LPWSTR x, LPWSTR y)
    751 {
    752         FIXME("%p(%s) %p(%s) stub\n",x,debugstr_w(x),y,debugstr_w(y));
    753         return TRUE;
    754 }
    755 
    756 DWORD WINAPI PathCleanupSpecAW (LPVOID x, LPVOID y)
    757 {
    758         if (VERSION_OsIsUnicode())
    759           return PathCleanupSpecW((LPWSTR)x,(LPWSTR)y);
    760         return PathCleanupSpecA((LPSTR)x,(LPSTR)y);
    761 }
    762 
    763 /*************************************************************************
    764  * SheGetDirW [SHELL32.281]
    765  *
    766  */
    767 HRESULT WINAPI SheGetDirW(LPWSTR u, LPWSTR v)
    768 {       FIXME("%p %p stub\n",u,v);
    769         return 0;
    770 }
    771 
    772 /*************************************************************************
    773  * SheChangeDirW [SHELL32.274]
    774  *
    775  */
    776 HRESULT WINAPI SheChangeDirW(LPWSTR u)
    777 {       FIXME("(%s),stub\n",debugstr_w(u));
    778         return 0;
    779 }
    780 
    781 /*************************************************************************
    782 *       PathProcessCommand      [SHELL32.653]
    783 */
    784 HRESULT WINAPI PathProcessCommandA (LPSTR lpCommand, LPSTR v, DWORD w, DWORD x)
    785 {
    786         FIXME("%p(%s) %p 0x%04lx 0x%04lx stub\n",
    787         lpCommand, lpCommand, v, w,x );
    788         return 0;
    789 }
    790 
    791 HRESULT WINAPI PathProcessCommandW (LPWSTR lpCommand, LPSTR v, DWORD w, DWORD x)
    792 {
    793         FIXME("%p(%s) %p 0x%04lx 0x%04lx stub\n",
    794         lpCommand, debugstr_w(lpCommand), v, w,x );
    795         return 0;
    796 }
    797 
    798 HRESULT WINAPI PathProcessCommandAW (LPVOID lpCommand, LPSTR v, DWORD w, DWORD x)
    799 {
    800         if (VERSION_OsIsUnicode())
    801           return PathProcessCommandW((LPWSTR)lpCommand, v, w, x);
    802         return PathProcessCommandA((LPSTR)lpCommand, v, w, x);
    803 }
    804 
    805 /*************************************************************************
    806  * SHGetSpecialFolderPath [SHELL32.175]
    807  *
    808  * converts csidl to path
    809  *
    810  */
    811 
    812 static char * szSHFolders = "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders";
    813 
    814 BOOL WINAPI SHGetSpecialFolderPathA (
    815         HWND hwndOwner,
    816         LPSTR szPath,
    817         DWORD csidl,
    818         BOOL bCreate)
    819 {
    820         CHAR    szValueName[MAX_PATH], szDefaultPath[MAX_PATH];
    821         HKEY    hRootKey, hKey;
    822         BOOL    bRelative = TRUE;
    823         DWORD   dwType, dwDisp, dwPathLen = MAX_PATH;
    824 
    825         TRACE("0x%04x,%p,csidl=%lu,0x%04x\n", hwndOwner,szPath,csidl,bCreate);
    826 
    827         /* build default values */
    828         switch(csidl)
    829         {
    830           case CSIDL_APPDATA:
    831             hRootKey = HKEY_CURRENT_USER;
    832             strcpy (szValueName, "AppData");
    833             strcpy (szDefaultPath, "AppData");
    834             break;
    835 
    836           case CSIDL_COOKIES:
    837             hRootKey = HKEY_CURRENT_USER;
    838             strcpy (szValueName, "Cookies");
    839             strcpy(szDefaultPath, "Cookies");
    840             break;
    841 
    842           case CSIDL_DESKTOPDIRECTORY:
    843             hRootKey = HKEY_CURRENT_USER;
    844             strcpy(szValueName, "Desktop");
    845             strcpy(szDefaultPath, "Desktop");
    846             break;
    847 
    848           case CSIDL_COMMON_DESKTOPDIRECTORY:
    849             hRootKey = HKEY_LOCAL_MACHINE;
    850             strcpy(szValueName, "Common Desktop");
    851             strcpy(szDefaultPath, "Desktop");
    852             break;
    853 
    854           case CSIDL_FAVORITES:
    855             hRootKey = HKEY_CURRENT_USER;
    856             strcpy(szValueName, "Favorites");
    857             strcpy(szDefaultPath, "Favorites");
    858             break;
    859 
    860           case CSIDL_FONTS:
    861             hRootKey = HKEY_CURRENT_USER;
    862             strcpy(szValueName, "Fonts");
    863             strcpy(szDefaultPath, "Fonts");
    864             break;
    865 
    866           case CSIDL_HISTORY:
    867             hRootKey = HKEY_CURRENT_USER;
    868             strcpy(szValueName, "History");
    869             strcpy(szDefaultPath, "History");
    870             break;
    871 
    872           case CSIDL_NETHOOD:
    873             hRootKey = HKEY_CURRENT_USER;
    874             strcpy(szValueName, "NetHood");
    875             strcpy(szDefaultPath, "NetHood");
    876             break;
    877 
    878           case CSIDL_INTERNET_CACHE:
    879             hRootKey = HKEY_CURRENT_USER;
    880             strcpy(szValueName, "Cache");
    881             strcpy(szDefaultPath, "Temporary Internet Files");
    882             break;
    883 
    884           case CSIDL_PERSONAL:
    885             hRootKey = HKEY_CURRENT_USER;
    886             strcpy(szValueName, "Personal");
    887             strcpy(szDefaultPath, "My Own Files");
    888             bRelative = FALSE;
    889             break;
    890 
    891           case CSIDL_PRINTHOOD:
    892             hRootKey = HKEY_CURRENT_USER;
    893             strcpy(szValueName, "PrintHood");
    894             strcpy(szDefaultPath, "PrintHood");
    895             break;
    896 
    897           case CSIDL_PROGRAMS:
    898             hRootKey = HKEY_CURRENT_USER;
    899             strcpy(szValueName, "Programs");
    900             strcpy(szDefaultPath, "StatrMenu\\Programs");
    901             break;
    902 
    903           case CSIDL_COMMON_PROGRAMS:
    904             hRootKey = HKEY_LOCAL_MACHINE;
    905             strcpy(szValueName, "Common Programs");
    906             strcpy(szDefaultPath, "");
    907             break;
    908 
    909           case CSIDL_RECENT:
    910             hRootKey = HKEY_CURRENT_USER;
    911             strcpy(szValueName, "Recent");
    912             strcpy(szDefaultPath, "Recent");
    913             break;
    914 
    915           case CSIDL_SENDTO:
    916             hRootKey = HKEY_CURRENT_USER;
    917             strcpy(szValueName, "SendTo");
    918             strcpy(szDefaultPath, "SendTo");
    919             break;
    920 
    921           case CSIDL_STARTMENU:
    922             hRootKey = HKEY_CURRENT_USER;
    923             strcpy(szValueName, "StartMenu");
    924             strcpy(szDefaultPath, "StartMenu");
    925             break;
    926 
    927           case CSIDL_COMMON_STARTMENU:
    928             hRootKey = HKEY_LOCAL_MACHINE;
    929             strcpy(szValueName, "Common StartMenu");
    930             strcpy(szDefaultPath, "StartMenu");
    931             break;
    932 
    933           case CSIDL_STARTUP:
    934             hRootKey = HKEY_CURRENT_USER;
    935             strcpy(szValueName, "Startup");
    936             strcpy(szDefaultPath, "StartMenu\\Programs\\Startup");
    937             break;
    938 
    939           case CSIDL_COMMON_STARTUP:
    940             hRootKey = HKEY_LOCAL_MACHINE;
    941             strcpy(szValueName, "Common Startup");
    942             strcpy(szDefaultPath, "StartMenu\\Programs\\Startup");
    943             break;
    944 
    945           case CSIDL_TEMPLATES:
    946             hRootKey = HKEY_CURRENT_USER;
    947             strcpy(szValueName, "Templates");
    948             strcpy(szDefaultPath, "ShellNew");
    949             break;
    950 
    951           default:
    952             ERR("folder unknown or not allowed\n");
    953             return FALSE;
    954         }
    955 
    956         if (RegCreateKeyExA(hRootKey,szSHFolders,0,NULL,REG_OPTION_NON_VOLATILE,KEY_WRITE,NULL,&hKey,&dwDisp))
    957         {
    958           return FALSE;
    959         }
    960 
    961         if (RegQueryValueExA(hKey,szValueName,NULL,&dwType,(LPBYTE)szPath,&dwPathLen))
    962         {
    963           /* value not existing */
    964           if (bRelative)
    965           {
    966             GetWindowsDirectoryA(szPath, MAX_PATH);
    967             PathAddBackslashA(szPath);
    968             strcat(szPath, szDefaultPath);
    969           }
    970           else
    971           {
    972             strcpy(szPath, szDefaultPath);
    973           }
    974           if (bCreate)
    975           {
    976             CreateDirectoryA(szPath,NULL);
    977           }
    978           RegSetValueExA(hKey,szValueName,0,REG_SZ,(LPBYTE)szPath,strlen(szPath)+1);
    979         }
    980         RegCloseKey(hKey);
    981 
    982         return TRUE;
    983 }
    984 BOOL WINAPI SHGetSpecialFolderPathW (
    985         HWND hwndOwner,
    986         LPWSTR szPath,
    987         DWORD csidl,
    988         BOOL bCreate)
    989 {
    990         char szTemp[MAX_PATH];
    991        
    992         if (SHGetSpecialFolderPathA(hwndOwner, szTemp, csidl, bCreate))
    993         {
    994           lstrcpynAtoW(szPath, szTemp, MAX_PATH);
    995         }
    996 
    997         TRACE("0x%04x,%p,csidl=%lu,0x%04x\n", hwndOwner,szPath,csidl,bCreate);
    998 
    999         return TRUE;
    1000 }
    1001 BOOL WINAPI SHGetSpecialFolderPathAW (
    1002         HWND hwndOwner,
    1003         LPVOID szPath,
    1004         DWORD csidl,
    1005         BOOL bCreate)
    1006 
    1007 {
    1008         if (VERSION_OsIsUnicode())
    1009           return SHGetSpecialFolderPathW (hwndOwner, (LPWSTR)szPath, csidl, bCreate);
    1010         return SHGetSpecialFolderPathA (hwndOwner, (LPSTR)szPath, csidl, bCreate);
    1011 }
  • trunk/src/shell32/shlmenu.cpp

    r1215 r1470  
    1 /* $Id: shlmenu.cpp,v 1.2 1999-10-09 11:17:05 sandervl Exp $ */
     1/* $Id: shlmenu.cpp,v 1.3 1999-10-27 09:33:48 phaller Exp $ */
     2
     3/*
     4 * Win32 SHELL32 for OS/2
     5 *
     6 * Copyright 1999 Patrick Haller (haller@zebra.fh-weingarten.de)
     7 * Project Odin Software License can be found in LICENSE.TXT
     8 *
     9 * Path Functions
     10 *
     11 * Many of this functions are in SHLWAPI.DLL also
     12 *
     13 */
     14
    215/*
    316 * see www.geocities.com/SiliconValley/4942/filemenu.html
    417 */
     18
     19
     20/*****************************************************************************
     21 * Includes                                                                  *
     22 *****************************************************************************/
     23
     24#include <odin.h>
     25#include <odinwrap.h>
     26#include <os2sel.h>
     27
    528#include <assert.h>
    629#include <string.h>
     
    2548#include <misc.h>
    2649
     50
     51ODINDEBUGCHANNEL(SHELL32-SHLMENU)
     52
     53
     54/*****************************************************************************
     55 * Implementation                                                            *
     56 *****************************************************************************/
     57
    2758BOOL WINAPI FileMenu_DeleteAllItems (HMENU hMenu);
    2859BOOL WINAPI FileMenu_AppendItemA(HMENU hMenu, LPCSTR lpText, UINT uID, int icon, HMENU hMenuPopup, int nItemHeight);
    2960
    3061typedef struct
    31 {       BOOL            bInitialized;
    32         BOOL            bIsMagic;
    33 
    34         /* create */
    35         COLORREF        crBorderColor;
    36         int             nBorderWidth;
    37         HBITMAP         hBorderBmp;
    38 
    39         /* insert using pidl */
    40         LPITEMIDLIST    pidl;
    41         UINT            uID;
    42         UINT            uFlags;
    43         UINT            uEnumFlags;
    44         LPFNFMCALLBACK lpfnCallback;
     62{  BOOL     bInitialized;
     63   BOOL     bIsMagic;
     64
     65   /* create */
     66   COLORREF crBorderColor;
     67   int      nBorderWidth;
     68   HBITMAP     hBorderBmp;
     69
     70   /* insert using pidl */
     71   LPITEMIDLIST   pidl;
     72   UINT     uID;
     73   UINT     uFlags;
     74   UINT     uEnumFlags;
     75   LPFNFMCALLBACK lpfnCallback;
    4576} FMINFO, *LPFMINFO;
    4677
    4778typedef struct
    48 {       int     cchItemText;
    49         int     iIconIndex;
    50         HMENU   hMenu;
    51         char    szItemText[1];
     79{  int   cchItemText;
     80   int   iIconIndex;
     81   HMENU hMenu;
     82   char  szItemText[1];
    5283} FMITEM, * LPFMITEM;
    5384
    5485static BOOL bAbortInit;
    5586
    56 #define CCH_MAXITEMTEXT 256
    57 
    58 DEFAULT_DEBUG_CHANNEL(shell)
     87#define  CCH_MAXITEMTEXT 256
    5988
    6089LPFMINFO FM_GetMenuInfo(HMENU hmenu)
    61 {       MENUINFO        MenuInfo;
    62         LPFMINFO        menudata;
    63 
    64         MenuInfo.cbSize = sizeof(MENUINFO);
    65         MenuInfo.fMask = MIM_MENUDATA;
    66 
    67         if (! GetMenuInfo(hmenu, &MenuInfo))
    68           return NULL;
    69 
    70         menudata = (LPFMINFO)MenuInfo.dwMenuData;
    71 
    72         assert ((menudata != 0) && (MenuInfo.cbSize == sizeof(MENUINFO)));
    73        
    74         return menudata;
    75 
    76 }
    77 /*************************************************************************
    78  * FM_SetMenuParameter                          [internal]
     90{  MENUINFO MenuInfo;
     91   LPFMINFO menudata;
     92
     93   MenuInfo.cbSize = sizeof(MENUINFO);
     94   MenuInfo.fMask = MIM_MENUDATA;
     95
     96   if (! GetMenuInfo(hmenu, &MenuInfo))
     97     return NULL;
     98
     99   menudata = (LPFMINFO)MenuInfo.dwMenuData;
     100
     101   assert ((menudata != 0) && (MenuInfo.cbSize == sizeof(MENUINFO)));
     102
     103   return menudata;
     104
     105}
     106/*************************************************************************
     107 * FM_SetMenuParameter                            [internal]
    79108 *
    80109 */
    81110static LPFMINFO FM_SetMenuParameter(
    82         HMENU hmenu,
    83         UINT uID,
    84         LPCITEMIDLIST pidl,
    85         UINT uFlags,
    86         UINT uEnumFlags,
    87         LPFNFMCALLBACK lpfnCallback)
    88 {
    89         LPFMINFO        menudata;
    90 
    91         TRACE("\n");
    92        
    93         menudata = FM_GetMenuInfo(hmenu);
    94        
    95         if ( menudata->pidl)
    96         { SHFree(menudata->pidl);
    97         }
    98        
    99         menudata->uID = uID;
    100         menudata->pidl = ILClone(pidl);
    101         menudata->uFlags = uFlags;
    102         menudata->uEnumFlags = uEnumFlags;
    103         menudata->lpfnCallback = lpfnCallback;
    104 
    105         return menudata;
    106 }
    107 
    108 /*************************************************************************
    109  * FM_InitMenuPopup                             [internal]
     111   HMENU hmenu,
     112   UINT uID,
     113   LPCITEMIDLIST pidl,
     114   UINT uFlags,
     115   UINT uEnumFlags,
     116   LPFNFMCALLBACK lpfnCallback)
     117{
     118   LPFMINFO menudata;
     119
     120   TRACE("\n");
     121
     122   menudata = FM_GetMenuInfo(hmenu);
     123
     124   if ( menudata->pidl)
     125   { SHFree(menudata->pidl);
     126   }
     127
     128   menudata->uID = uID;
     129   menudata->pidl = ILClone(pidl);
     130   menudata->uFlags = uFlags;
     131   menudata->uEnumFlags = uEnumFlags;
     132   menudata->lpfnCallback = lpfnCallback;
     133
     134   return menudata;
     135}
     136
     137/*************************************************************************
     138 * FM_InitMenuPopup                               [internal]
    110139 *
    111140 */
    112141static int FM_InitMenuPopup(HMENU hmenu, LPITEMIDLIST pAlternatePidl)
    113 {       IShellFolder    *lpsf, *lpsf2;
    114         ULONG           ulItemAttr;
    115         UINT            uID, uFlags, uEnumFlags;
    116         LPFNFMCALLBACK  lpfnCallback;
    117         LPITEMIDLIST    pidl;
    118         char            sTemp[MAX_PATH];
    119         int             NumberOfItems = 0, iIcon;
    120         MENUINFO        MenuInfo;
    121         LPFMINFO        menudata;
    122 
    123         TRACE("0x%04x %p\n", hmenu, pAlternatePidl);
    124 
    125         MenuInfo.cbSize = sizeof(MENUINFO);
    126         MenuInfo.fMask = MIM_MENUDATA;
    127 
    128         if (! GetMenuInfo(hmenu, &MenuInfo))
    129           return FALSE;
    130 
    131         menudata = (LPFMINFO)MenuInfo.dwMenuData;
    132        
    133         assert ((menudata != 0) && (MenuInfo.cbSize == sizeof(MENUINFO)));
    134        
    135         if (menudata->bInitialized)
    136           return 0;
    137        
    138         uID = menudata->uID;
    139         pidl = ((pAlternatePidl) ? pAlternatePidl : menudata->pidl);
    140         uFlags = menudata->uFlags;
    141         uEnumFlags = menudata->uEnumFlags;
    142         lpfnCallback = menudata->lpfnCallback;
    143 
    144         menudata->bInitialized = FALSE;
    145         SetMenuInfo(hmenu, &MenuInfo);
    146        
    147         if (SUCCEEDED (SHGetDesktopFolder(&lpsf)))
    148         {
    149           if (SUCCEEDED(IShellFolder_BindToObject(lpsf, pidl,0,(REFIID)&IID_IShellFolder,(LPVOID *)&lpsf2)))
    150           {
    151             IEnumIDList *lpe = NULL;
    152 
    153             if (SUCCEEDED (IShellFolder_EnumObjects(lpsf2, 0, uEnumFlags, &lpe )))
    154             {
    155 
    156               LPITEMIDLIST pidlTemp = NULL;
    157               ULONG ulFetched;
    158 
    159               while ((!bAbortInit) && (NOERROR == IEnumIDList_Next(lpe,1,&pidlTemp,&ulFetched)))
    160               {
    161                 if (SUCCEEDED (IShellFolder_GetAttributesOf(lpsf, 1, &pidlTemp, &ulItemAttr)))
    162                 {
    163                   ILGetDisplayName( pidlTemp, sTemp);
    164                   if (! (PidlToSicIndex(lpsf, pidlTemp, FALSE, (UINT*)&iIcon)))
    165                     iIcon = FM_BLANK_ICON;
    166                   if ( SFGAO_FOLDER & ulItemAttr)
    167                   {
    168                     LPFMINFO lpFmMi;
    169                     MENUINFO MenuInfo;
    170                     HMENU hMenuPopup = CreatePopupMenu();
    171        
    172                     lpFmMi = (LPFMINFO) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(FMINFO));
    173 
    174                     lpFmMi->pidl = ILCombine(pidl, pidlTemp);
    175                     lpFmMi->uEnumFlags = SHCONTF_FOLDERS | SHCONTF_NONFOLDERS;
    176 
    177                     MenuInfo.cbSize = sizeof(MENUINFO);
    178                     MenuInfo.fMask = MIM_MENUDATA;
    179                     MenuInfo.dwMenuData = (DWORD) lpFmMi;
    180                     SetMenuInfo (hMenuPopup, &MenuInfo);
    181 
    182                     FileMenu_AppendItemA (hmenu, sTemp, uID, iIcon, hMenuPopup, FM_DEFAULT_HEIGHT);
    183                   }
    184                   else
    185                   {
    186                     ((LPSTR)PathFindExtensionA(sTemp))[0] = 0x00;
    187                     FileMenu_AppendItemA (hmenu, sTemp, uID, iIcon, 0, FM_DEFAULT_HEIGHT);
    188                   }
    189                 }
    190 
    191                 if (lpfnCallback)
    192                 {
    193                   TRACE("enter callback\n");
    194                   lpfnCallback ( pidl, pidlTemp);
    195                   TRACE("leave callback\n");
    196                 }
    197 
    198                 NumberOfItems++;
    199               }
    200               IEnumIDList_Release (lpe);
    201             }
    202             IShellFolder_Release(lpsf2);
    203           }
    204           IShellFolder_Release(lpsf);
    205         }
    206 
    207         if ( GetMenuItemCount (hmenu) == 0 )
    208         { FileMenu_AppendItemA (hmenu, "(empty)", uID, FM_BLANK_ICON, 0, FM_DEFAULT_HEIGHT);
    209           NumberOfItems++;
    210         }
    211 
    212         menudata->bInitialized = TRUE;
    213         SetMenuInfo(hmenu, &MenuInfo);
    214 
    215         return NumberOfItems;
    216 }
    217 /*************************************************************************
    218  * FileMenu_Create                              [SHELL32.114]
    219  *
    220  */
    221 HMENU WINAPI FileMenu_Create (
    222         COLORREF crBorderColor,
    223         int nBorderWidth,
    224         HBITMAP hBorderBmp,
    225         int nSelHeight,
    226         UINT uFlags)
    227 {
    228         MENUINFO        MenuInfo;
    229         LPFMINFO        menudata;
    230 
    231         HMENU hMenu = CreatePopupMenu();
    232 
    233         TRACE("0x%08lx 0x%08x 0x%08x 0x%08x 0x%08x  hMenu=0x%08x\n",
    234         crBorderColor, nBorderWidth, hBorderBmp, nSelHeight, uFlags, hMenu);
    235 
    236         menudata = (LPFMINFO)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(FMINFO));
    237         menudata->bIsMagic = TRUE;
    238         menudata->crBorderColor = crBorderColor;
    239         menudata->nBorderWidth = nBorderWidth;
    240         menudata->hBorderBmp = hBorderBmp;
    241 
    242         MenuInfo.cbSize = sizeof(MENUINFO);
    243         MenuInfo.fMask = MIM_MENUDATA;
    244         MenuInfo.dwMenuData = (DWORD) menudata;
    245         SetMenuInfo (hMenu, &MenuInfo);
    246 
    247         return hMenu;
    248 }
    249 
    250 /*************************************************************************
    251  * FileMenu_Destroy                             [SHELL32.118]
     142{  IShellFolder   *lpsf, *lpsf2;
     143   ULONG    ulItemAttr;
     144   UINT     uID, uFlags, uEnumFlags;
     145   LPFNFMCALLBACK lpfnCallback;
     146   LPITEMIDLIST   pidl;
     147   char     sTemp[MAX_PATH];
     148   int      NumberOfItems = 0, iIcon;
     149   MENUINFO MenuInfo;
     150   LPFMINFO menudata;
     151
     152   TRACE("0x%04x %p\n", hmenu, pAlternatePidl);
     153
     154   MenuInfo.cbSize = sizeof(MENUINFO);
     155   MenuInfo.fMask = MIM_MENUDATA;
     156
     157   if (! GetMenuInfo(hmenu, &MenuInfo))
     158     return FALSE;
     159
     160   menudata = (LPFMINFO)MenuInfo.dwMenuData;
     161
     162   assert ((menudata != 0) && (MenuInfo.cbSize == sizeof(MENUINFO)));
     163
     164   if (menudata->bInitialized)
     165     return 0;
     166
     167   uID = menudata->uID;
     168   pidl = ((pAlternatePidl) ? pAlternatePidl : menudata->pidl);
     169   uFlags = menudata->uFlags;
     170   uEnumFlags = menudata->uEnumFlags;
     171   lpfnCallback = menudata->lpfnCallback;
     172
     173   menudata->bInitialized = FALSE;
     174   SetMenuInfo(hmenu, &MenuInfo);
     175
     176   if (SUCCEEDED (SHGetDesktopFolder(&lpsf)))
     177   {
     178     if (SUCCEEDED(IShellFolder_BindToObject(lpsf, pidl,0,(REFIID)&IID_IShellFolder,(LPVOID *)&lpsf2)))
     179     {
     180       IEnumIDList                       *lpe = NULL;
     181
     182       if (SUCCEEDED (IShellFolder_EnumObjects(lpsf2, 0, uEnumFlags, &lpe )))
     183       {
     184
     185         LPITEMIDLIST pidlTemp = NULL;
     186         ULONG ulFetched;
     187
     188         while ((!bAbortInit) && (NOERROR == IEnumIDList_Next(lpe,1,&pidlTemp,&ulFetched)))
     189         {
     190      if (SUCCEEDED (IShellFolder_GetAttributesOf(lpsf, 1, &pidlTemp, &ulItemAttr)))
     191      {
     192        ILGetDisplayName( pidlTemp, sTemp);
     193        if (! (PidlToSicIndex(lpsf, pidlTemp, FALSE, (UINT*)&iIcon)))
     194          iIcon = FM_BLANK_ICON;
     195        if ( SFGAO_FOLDER & ulItemAttr)
     196        {
     197          LPFMINFO lpFmMi;
     198          MENUINFO MenuInfo;
     199          HMENU hMenuPopup = CreatePopupMenu();
     200
     201          lpFmMi = (LPFMINFO) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(FMINFO));
     202
     203          lpFmMi->pidl = ILCombine(pidl, pidlTemp);
     204          lpFmMi->uEnumFlags = SHCONTF_FOLDERS | SHCONTF_NONFOLDERS;
     205
     206          MenuInfo.cbSize = sizeof(MENUINFO);
     207          MenuInfo.fMask = MIM_MENUDATA;
     208          MenuInfo.dwMenuData = (DWORD) lpFmMi;
     209          SetMenuInfo (hMenuPopup, &MenuInfo);
     210
     211          FileMenu_AppendItemA (hmenu, sTemp, uID, iIcon, hMenuPopup, FM_DEFAULT_HEIGHT);
     212        }
     213        else
     214        {
     215          ((LPSTR)PathFindExtensionA(sTemp))[0] = 0x00;
     216          FileMenu_AppendItemA (hmenu, sTemp, uID, iIcon, 0, FM_DEFAULT_HEIGHT);
     217        }
     218      }
     219
     220      if (lpfnCallback)
     221      {
     222        TRACE("enter callback\n");
     223        lpfnCallback ( pidl, pidlTemp);
     224        TRACE("leave callback\n");
     225      }
     226
     227      NumberOfItems++;
     228         }
     229         IEnumIDList_Release (lpe);
     230       }
     231       IShellFolder_Release(lpsf2);
     232     }
     233     IShellFolder_Release(lpsf);
     234   }
     235
     236   if ( GetMenuItemCount (hmenu) == 0 )
     237   { FileMenu_AppendItemA (hmenu, "(empty)", uID, FM_BLANK_ICON, 0, FM_DEFAULT_HEIGHT);
     238     NumberOfItems++;
     239   }
     240
     241   menudata->bInitialized = TRUE;
     242   SetMenuInfo(hmenu, &MenuInfo);
     243
     244   return NumberOfItems;
     245}
     246/*************************************************************************
     247 * FileMenu_Create                                [SHELL32.114]
     248 *
     249 */
     250ODINFUNCTION5(HMENU, FileMenu_Create,
     251              COLORREF, crBorderColor,
     252              int, nBorderWidth,
     253              HBITMAP, hBorderBmp,
     254              int, nSelHeight,
     255              UINT, uFlags)
     256{
     257   MENUINFO MenuInfo;
     258   LPFMINFO menudata;
     259
     260   HMENU hMenu = CreatePopupMenu();
     261
     262   TRACE("0x%08lx 0x%08x 0x%08x 0x%08x 0x%08x  hMenu=0x%08x\n",
     263   crBorderColor, nBorderWidth, hBorderBmp, nSelHeight, uFlags, hMenu);
     264
     265   menudata = (LPFMINFO)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(FMINFO));
     266   menudata->bIsMagic = TRUE;
     267   menudata->crBorderColor = crBorderColor;
     268   menudata->nBorderWidth = nBorderWidth;
     269   menudata->hBorderBmp = hBorderBmp;
     270
     271   MenuInfo.cbSize = sizeof(MENUINFO);
     272   MenuInfo.fMask = MIM_MENUDATA;
     273   MenuInfo.dwMenuData = (DWORD) menudata;
     274   SetMenuInfo (hMenu, &MenuInfo);
     275
     276   return hMenu;
     277}
     278
     279/*************************************************************************
     280 * FileMenu_Destroy                               [SHELL32.118]
    252281 *
    253282 * NOTES
    254283 *  exported by name
    255284 */
    256 void WINAPI FileMenu_Destroy (HMENU hmenu)
    257 {
    258         LPFMINFO        menudata;
    259 
    260         TRACE("0x%08x\n", hmenu);
    261 
    262         FileMenu_DeleteAllItems (hmenu);
    263        
    264         menudata = FM_GetMenuInfo(hmenu);
    265 
    266         if ( menudata->pidl)
    267         { SHFree( menudata->pidl);
    268         }
    269         HeapFree(GetProcessHeap(), 0, menudata);
    270 
    271         DestroyMenu (hmenu);
    272 }
    273 
    274 /*************************************************************************
    275  * FileMenu_AppendItemAW                        [SHELL32.115]
    276  *
    277  */
    278 BOOL WINAPI FileMenu_AppendItemA(
    279         HMENU hMenu,
    280         LPCSTR lpText,
    281         UINT uID,
    282         int icon,
    283         HMENU hMenuPopup,
    284         int nItemHeight)
    285 {
    286         LPSTR lpszText = (LPSTR)lpText;
    287         MENUITEMINFOA   mii;
    288         LPFMITEM myItem;
    289 
    290         TRACE("0x%08x %s 0x%08x 0x%08x 0x%08x 0x%08x\n",
    291         hMenu, (lpszText!=FM_SEPARATOR) ? lpText: NULL,
    292         uID, icon, hMenuPopup, nItemHeight);
    293        
    294         ZeroMemory (&mii, sizeof(MENUITEMINFOA));
    295        
    296         mii.cbSize = sizeof(MENUITEMINFOA);
    297 
    298         if (lpText != FM_SEPARATOR)
    299         { int len = strlen (lpText);
    300           myItem = (LPFMITEM) SHAlloc( sizeof(FMITEM) + len);
    301           strcpy (myItem->szItemText, lpText);
    302           myItem->cchItemText = len;
    303           myItem->iIconIndex = icon;
    304           myItem->hMenu = hMenu;
    305           mii.fMask = MIIM_DATA;
    306           mii.dwItemData = (DWORD) myItem;
    307         }
    308        
    309         if ( hMenuPopup )
    310         { /* sub menu */
    311           mii.fMask |= MIIM_TYPE | MIIM_SUBMENU;
    312           mii.fType = MFT_OWNERDRAW;
    313           mii.hSubMenu = hMenuPopup;
    314         }
    315         else if (lpText == FM_SEPARATOR )
    316         { mii.fMask |= MIIM_ID | MIIM_TYPE;
    317           mii.fType = MFT_SEPARATOR;
    318         }
    319         else
    320         { /* normal item */
    321           mii.fMask |= MIIM_ID | MIIM_TYPE | MIIM_STATE;
    322           mii.fState = MFS_ENABLED | MFS_DEFAULT;
    323           mii.fType = MFT_OWNERDRAW;
    324         }
    325         mii.wID = uID;
    326 
    327         InsertMenuItemA (hMenu, (UINT)-1, TRUE, &mii);
    328 
    329         return TRUE;
    330 
    331 }
    332 BOOL WINAPI FileMenu_AppendItemAW(
    333         HMENU hMenu,
    334         LPCVOID lpText,
    335         UINT uID,
    336         int icon,
    337         HMENU hMenuPopup,
    338         int nItemHeight)
    339 {
    340         BOOL ret;
    341         LPSTR lpszText=NULL;
    342 
    343         if (VERSION_OsIsUnicode() && (lpText!=FM_SEPARATOR))
    344           lpszText = (LPSTR)HEAP_strdupWtoA ( GetProcessHeap(),0, (LPCWSTR)lpText);
    345 
    346         ret = FileMenu_AppendItemA(hMenu, (lpszText) ? lpszText : (LPCSTR)lpText, uID, icon, hMenuPopup, nItemHeight);
    347 
    348         if (lpszText)
    349           HeapFree( GetProcessHeap(), 0, lpszText );
    350 
    351         return ret;
    352 }
    353 /*************************************************************************
    354  * FileMenu_InsertUsingPidl                     [SHELL32.110]
     285ODINPROCEDURE1(FileMenu_Destroy,
     286               HMENU, hmenu)
     287{
     288   LPFMINFO menudata;
     289
     290   TRACE("0x%08x\n", hmenu);
     291
     292   FileMenu_DeleteAllItems (hmenu);
     293
     294   menudata = FM_GetMenuInfo(hmenu);
     295
     296   if ( menudata->pidl)
     297   { SHFree( menudata->pidl);
     298   }
     299   HeapFree(GetProcessHeap(), 0, menudata);
     300
     301   DestroyMenu (hmenu);
     302}
     303
     304/*************************************************************************
     305 * FileMenu_AppendItemAW                       [SHELL32.115]
     306 *
     307 */
     308ODINFUNCTION6(BOOL, FileMenu_AppendItemA,
     309              HMENU, hMenu,
     310              LPCSTR, lpText,
     311              UINT, uID,
     312              int, icon,
     313              HMENU, hMenuPopup,
     314              int, nItemHeight)
     315{
     316   LPSTR lpszText = (LPSTR)lpText;
     317   MENUITEMINFOA  mii;
     318   LPFMITEM myItem;
     319
     320   TRACE("0x%08x %s 0x%08x 0x%08x 0x%08x 0x%08x\n",
     321   hMenu, (lpszText!=FM_SEPARATOR) ? lpText: NULL,
     322   uID, icon, hMenuPopup, nItemHeight);
     323
     324   ZeroMemory (&mii, sizeof(MENUITEMINFOA));
     325
     326   mii.cbSize = sizeof(MENUITEMINFOA);
     327
     328   if (lpText != FM_SEPARATOR)
     329   { int len = strlen (lpText);
     330     myItem = (LPFMITEM) SHAlloc( sizeof(FMITEM) + len);
     331     strcpy (myItem->szItemText, lpText);
     332     myItem->cchItemText = len;
     333     myItem->iIconIndex = icon;
     334     myItem->hMenu = hMenu;
     335     mii.fMask = MIIM_DATA;
     336     mii.dwItemData = (DWORD) myItem;
     337   }
     338
     339   if ( hMenuPopup )
     340   { /* sub menu */
     341     mii.fMask |= MIIM_TYPE | MIIM_SUBMENU;
     342     mii.fType = MFT_OWNERDRAW;
     343     mii.hSubMenu = hMenuPopup;
     344   }
     345   else if (lpText == FM_SEPARATOR )
     346   { mii.fMask |= MIIM_ID | MIIM_TYPE;
     347     mii.fType = MFT_SEPARATOR;
     348   }
     349   else
     350   { /* normal item */
     351     mii.fMask |= MIIM_ID | MIIM_TYPE | MIIM_STATE;
     352     mii.fState = MFS_ENABLED | MFS_DEFAULT;
     353     mii.fType = MFT_OWNERDRAW;
     354   }
     355   mii.wID = uID;
     356
     357   InsertMenuItemA (hMenu, (UINT)-1, TRUE, &mii);
     358
     359   return TRUE;
     360
     361}
     362ODINFUNCTION6(BOOL, FileMenu_AppendItemAW,
     363              HMENU, hMenu,
     364              LPCVOID, lpText,
     365              UINT, uID,
     366              int, icon,
     367              HMENU, hMenuPopup,
     368              int, nItemHeight)
     369{
     370   BOOL ret;
     371   LPSTR lpszText=NULL;
     372
     373   if (VERSION_OsIsUnicode() && (lpText!=FM_SEPARATOR))
     374     lpszText = (LPSTR)HEAP_strdupWtoA ( GetProcessHeap(),0, (LPCWSTR)lpText);
     375
     376   ret = FileMenu_AppendItemA(hMenu, (lpszText) ? lpszText : (LPCSTR)lpText, uID, icon, hMenuPopup, nItemHeight);
     377
     378   if (lpszText)
     379     HeapFree( GetProcessHeap(), 0, lpszText );
     380
     381   return ret;
     382}
     383/*************************************************************************
     384 * FileMenu_InsertUsingPidl                    [SHELL32.110]
    355385 *
    356386 * NOTES
    357  *      uEnumFlags      any SHCONTF flag
    358  */
    359 int WINAPI FileMenu_InsertUsingPidl (
    360         HMENU hmenu,
    361         UINT uID,
    362         LPCITEMIDLIST pidl,
    363         UINT uFlags,
    364         UINT uEnumFlags,
    365         LPFNFMCALLBACK lpfnCallback)
    366 {       
    367         TRACE("0x%08x 0x%08x %p 0x%08x 0x%08x %p\n",
    368         hmenu, uID, pidl, uFlags, uEnumFlags, lpfnCallback);
    369 
    370         pdump (pidl);
    371 
    372         bAbortInit = FALSE;
    373 
    374         FM_SetMenuParameter(hmenu, uID, pidl, uFlags, uEnumFlags, lpfnCallback);       
    375 
    376         return FM_InitMenuPopup(hmenu, NULL);
    377 }
    378 
    379 /*************************************************************************
    380  * FileMenu_ReplaceUsingPidl                    [SHELL32.113]
    381  *
    382  */
    383 int WINAPI FileMenu_ReplaceUsingPidl(
    384         HMENU   hmenu,
    385         UINT    uID,
    386         LPCITEMIDLIST   pidl,
    387         UINT    uEnumFlags,
    388         LPFNFMCALLBACK lpfnCallback)
    389 {
    390         TRACE("0x%08x 0x%08x %p 0x%08x %p\n",
    391         hmenu, uID, pidl, uEnumFlags, lpfnCallback);
    392        
    393         FileMenu_DeleteAllItems (hmenu);
    394 
    395         FM_SetMenuParameter(hmenu, uID, pidl, 0, uEnumFlags, lpfnCallback);     
    396 
    397         return FM_InitMenuPopup(hmenu, NULL);
    398 }
    399 
    400 /*************************************************************************
    401  * FileMenu_Invalidate                  [SHELL32.111]
    402  */
    403 void WINAPI FileMenu_Invalidate (HMENU hMenu)
    404 {
    405         FIXME("0x%08x\n",hMenu);       
    406 }
    407 
    408 /*************************************************************************
    409  * FileMenu_FindSubMenuByPidl                   [SHELL32.106]
    410  */
    411 HMENU WINAPI FileMenu_FindSubMenuByPidl(
    412         HMENU   hMenu,
    413         LPCITEMIDLIST   pidl)
    414 {
    415         FIXME("0x%08x %p\n",hMenu, pidl);       
    416         return 0;
    417 }
    418 
    419 /*************************************************************************
    420  * FileMenu_AppendFilesForPidl                  [SHELL32.124]
    421  */
    422 HMENU WINAPI FileMenu_AppendFilesForPidl(
    423         HMENU   hmenu,
    424         LPCITEMIDLIST   pidl,
    425         BOOL    bAddSeperator)
    426 {
    427         LPFMINFO        menudata;
    428 
    429         menudata = FM_GetMenuInfo(hmenu);
    430        
    431         menudata->bInitialized = FALSE;
    432        
    433         FM_InitMenuPopup(hmenu, pidl);
    434 
    435         if (bAddSeperator)
    436           FileMenu_AppendItemA (hmenu, FM_SEPARATOR, 0, 0, 0, FM_DEFAULT_HEIGHT);
    437 
    438         TRACE("0x%08x %p 0x%08x\n",hmenu, pidl,bAddSeperator); 
    439 
    440         return 0;
    441 }
    442 /*************************************************************************
    443  * FileMenu_AddFilesForPidl                     [SHELL32.125]
     387 * uEnumFlags  any SHCONTF flag
     388 */
     389ODINFUNCTION6(int, FileMenu_InsertUsingPidl,
     390              HMENU, hmenu,
     391              UINT, uID,
     392              LPCITEMIDLIST, pidl,
     393              UINT, uFlags,
     394              UINT, uEnumFlags,
     395              LPFNFMCALLBACK, lpfnCallback)
     396{
     397   TRACE("0x%08x 0x%08x %p 0x%08x 0x%08x %p\n",
     398   hmenu, uID, pidl, uFlags, uEnumFlags, lpfnCallback);
     399
     400   pdump (pidl);
     401
     402   bAbortInit = FALSE;
     403
     404   FM_SetMenuParameter(hmenu, uID, pidl, uFlags, uEnumFlags, lpfnCallback);
     405
     406   return FM_InitMenuPopup(hmenu, NULL);
     407}
     408
     409/*************************************************************************
     410 * FileMenu_ReplaceUsingPidl                   [SHELL32.113]
     411 *
     412 */
     413ODINFUNCTION5(int, FileMenu_ReplaceUsingPidl,
     414              HMENU, hmenu,
     415              UINT, uID,
     416              LPCITEMIDLIST, pidl,
     417              UINT, uEnumFlags,
     418              LPFNFMCALLBACK, lpfnCallback)
     419{
     420   TRACE("0x%08x 0x%08x %p 0x%08x %p\n",
     421   hmenu, uID, pidl, uEnumFlags, lpfnCallback);
     422
     423   FileMenu_DeleteAllItems (hmenu);
     424
     425   FM_SetMenuParameter(hmenu, uID, pidl, 0, uEnumFlags, lpfnCallback);
     426
     427   return FM_InitMenuPopup(hmenu, NULL);
     428}
     429
     430/*************************************************************************
     431 * FileMenu_Invalidate                         [SHELL32.111]
     432 */
     433ODINPROCEDURE1(FileMenu_Invalidate,
     434               HMENU, hMenu)
     435{
     436   FIXME("0x%08x\n",hMenu);
     437}
     438
     439/*************************************************************************
     440 * FileMenu_FindSubMenuByPidl                  [SHELL32.106]
     441 */
     442ODINFUNCTION2(HMENU, FileMenu_FindSubMenuByPidl,
     443              HMENU, hMenu,
     444              LPCITEMIDLIST, pidl)
     445{
     446   FIXME("0x%08x %p\n",hMenu, pidl);
     447   return 0;
     448}
     449
     450/*************************************************************************
     451 * FileMenu_AppendFilesForPidl                 [SHELL32.124]
     452 */
     453ODINFUNCTION3(HMENU, FileMenu_AppendFilesForPidl,
     454              HMENU, hmenu,
     455              LPCITEMIDLIST, pidl,
     456              BOOL, bAddSeperator)
     457{
     458   LPFMINFO menudata;
     459
     460   menudata = FM_GetMenuInfo(hmenu);
     461
     462   menudata->bInitialized = FALSE;
     463
     464   FM_InitMenuPopup(hmenu, pidl);
     465
     466   if (bAddSeperator)
     467     FileMenu_AppendItemA (hmenu, FM_SEPARATOR, 0, 0, 0, FM_DEFAULT_HEIGHT);
     468
     469   TRACE("0x%08x %p 0x%08x\n",hmenu, pidl,bAddSeperator);
     470
     471   return 0;
     472}
     473/*************************************************************************
     474 * FileMenu_AddFilesForPidl                    [SHELL32.125]
    444475 *
    445476 * NOTES
    446  *      uEnumFlags      any SHCONTF flag
    447  */
    448 int WINAPI FileMenu_AddFilesForPidl (
    449         HMENU   hmenu,
    450         UINT    uReserved,
    451         UINT    uID,
    452         LPCITEMIDLIST   pidl,
    453         UINT    uFlags,
    454         UINT    uEnumFlags,
    455         LPFNFMCALLBACK  lpfnCallback)
    456 {
    457         TRACE("0x%08x 0x%08x 0x%08x %p 0x%08x 0x%08x %p\n",
    458         hmenu, uReserved, uID, pidl, uFlags, uEnumFlags, lpfnCallback);
    459 
    460         return FileMenu_InsertUsingPidl ( hmenu, uID, pidl, uFlags, uEnumFlags, lpfnCallback);
    461 
    462 }
    463 
    464 
    465 /*************************************************************************
    466  * FileMenu_TrackPopupMenuEx                    [SHELL32.116]
    467  */
    468 HRESULT WINAPI FileMenu_TrackPopupMenuEx (
    469         HMENU hMenu,
    470         UINT uFlags,
    471         int x,
    472         int y,
    473         HWND hWnd,
    474         LPTPMPARAMS lptpm)
    475 {
    476         TRACE("0x%08x 0x%08x 0x%x 0x%x 0x%08x %p\n",
    477         hMenu, uFlags, x, y, hWnd, lptpm);
    478         return TrackPopupMenuEx(hMenu, uFlags, x, y, hWnd, lptpm);
    479 }
    480 
    481 /*************************************************************************
    482  * FileMenu_GetLastSelectedItemPidls            [SHELL32.107]
    483  */
    484 BOOL WINAPI FileMenu_GetLastSelectedItemPidls(
    485         UINT    uReserved,
    486         LPCITEMIDLIST   *ppidlFolder,
    487         LPCITEMIDLIST   *ppidlItem)
    488 {
    489         FIXME("0x%08x %p %p\n",uReserved, ppidlFolder, ppidlItem);
    490         return 0;
    491 }
    492 
    493 #define FM_ICON_SIZE    16
    494 #define FM_Y_SPACE      4
    495 #define FM_SPACE1       4
    496 #define FM_SPACE2       2
    497 #define FM_LEFTBORDER   2
    498 #define FM_RIGHTBORDER  8
    499 /*************************************************************************
    500  * FileMenu_MeasureItem                         [SHELL32.112]
    501  */
    502 LRESULT WINAPI FileMenu_MeasureItem(
    503         HWND    hWnd,
    504         LPMEASUREITEMSTRUCT     lpmis)
    505 {
    506         LPFMITEM pMyItem = (LPFMITEM)(lpmis->itemData);
    507         HDC hdc = GetDC(hWnd);
    508         SIZE size;
    509         LPFMINFO menuinfo;
    510                
    511         TRACE("0x%08x %p %s\n", hWnd, lpmis, pMyItem->szItemText);
    512        
    513         GetTextExtentPoint32A(hdc, pMyItem->szItemText, pMyItem->cchItemText, &size);
    514        
    515         lpmis->itemWidth = size.cx + FM_LEFTBORDER + FM_ICON_SIZE + FM_SPACE1 + FM_SPACE2 + FM_RIGHTBORDER;
    516         lpmis->itemHeight = (size.cy > (FM_ICON_SIZE + FM_Y_SPACE)) ? size.cy : (FM_ICON_SIZE + FM_Y_SPACE);
    517 
    518         /* add the menubitmap */
    519         menuinfo = FM_GetMenuInfo(pMyItem->hMenu);
    520         if (menuinfo->bIsMagic)
    521           lpmis->itemWidth += menuinfo->nBorderWidth;
    522        
    523         TRACE("-- 0x%04x 0x%04x\n", lpmis->itemWidth, lpmis->itemHeight);
    524         ReleaseDC (hWnd, hdc);
    525         return 0;
    526 }
    527 /*************************************************************************
    528  * FileMenu_DrawItem                            [SHELL32.105]
    529  */
    530 LRESULT WINAPI FileMenu_DrawItem(
    531         HWND                    hWnd,
    532         LPDRAWITEMSTRUCT        lpdis)
    533 {
    534         LPFMITEM pMyItem = (LPFMITEM)(lpdis->itemData);
    535         COLORREF clrPrevText, clrPrevBkgnd;
    536         int xi,yi,xt,yt;
    537         HIMAGELIST hImageList;
    538         RECT TextRect, BorderRect;
    539         LPFMINFO menuinfo;
    540        
    541         TRACE("0x%08x %p %s\n", hWnd, lpdis, pMyItem->szItemText);
    542        
    543         if (lpdis->itemState & ODS_SELECTED)
    544         {
    545           clrPrevText = SetTextColor(lpdis->hDC, GetSysColor (COLOR_HIGHLIGHTTEXT));
    546           clrPrevBkgnd = SetBkColor(lpdis->hDC, GetSysColor (COLOR_HIGHLIGHT));
    547         }
    548         else
    549         {
    550           clrPrevText = SetTextColor(lpdis->hDC, GetSysColor (COLOR_MENUTEXT));
    551           clrPrevBkgnd = SetBkColor(lpdis->hDC, GetSysColor (COLOR_MENU));
    552         }
    553        
    554         CopyRect(&TextRect, &(lpdis->rcItem));
    555 
    556         /* add the menubitmap */
    557         menuinfo = FM_GetMenuInfo(pMyItem->hMenu);
    558         if (menuinfo->bIsMagic)
    559           TextRect.left += menuinfo->nBorderWidth;
    560        
    561         BorderRect.right = menuinfo->nBorderWidth;
    562 /*      FillRect(lpdis->hDC, &BorderRect, CreateSolidBrush( menuinfo->crBorderColor));
     477 * uEnumFlags  any SHCONTF flag
     478 */
     479ODINFUNCTION7(int, FileMenu_AddFilesForPidl,
     480              HMENU, hmenu,
     481              UINT, uReserved,
     482              UINT, uID,
     483              LPCITEMIDLIST, pidl,
     484              UINT, uFlags,
     485              UINT, uEnumFlags,
     486              LPFNFMCALLBACK, lpfnCallback)
     487{
     488   TRACE("0x%08x 0x%08x 0x%08x %p 0x%08x 0x%08x %p\n",
     489   hmenu, uReserved, uID, pidl, uFlags, uEnumFlags, lpfnCallback);
     490
     491   return FileMenu_InsertUsingPidl ( hmenu, uID, pidl, uFlags, uEnumFlags, lpfnCallback);
     492
     493}
     494
     495
     496/*************************************************************************
     497 * FileMenu_TrackPopupMenuEx                   [SHELL32.116]
     498 */
     499ODINFUNCTION6(HRESULT, FileMenu_TrackPopupMenuEx,
     500              HMENU, hMenu,
     501              UINT, uFlags,
     502              int, x,
     503              int, y,
     504              HWND, hWnd,
     505              LPTPMPARAMS, lptpm)
     506{
     507   TRACE("0x%08x 0x%08x 0x%x 0x%x 0x%08x %p\n",
     508   hMenu, uFlags, x, y, hWnd, lptpm);
     509   return TrackPopupMenuEx(hMenu, uFlags, x, y, hWnd, lptpm);
     510}
     511
     512/*************************************************************************
     513 * FileMenu_GetLastSelectedItemPidls        [SHELL32.107]
     514 */
     515ODINFUNCTION3(BOOL, FileMenu_GetLastSelectedItemPidls,
     516              UINT, uReserved,
     517              LPCITEMIDLIST *, ppidlFolder,
     518              LPCITEMIDLIST *, ppidlItem)
     519{
     520   FIXME("0x%08x %p %p\n",uReserved, ppidlFolder, ppidlItem);
     521   return 0;
     522}
     523
     524#define FM_ICON_SIZE                     16
     525#define FM_Y_SPACE                       4
     526#define FM_SPACE1 4
     527#define FM_SPACE2 2
     528#define FM_LEFTBORDER                    2
     529#define FM_RIGHTBORDER                   8
     530/*************************************************************************
     531 * FileMenu_MeasureItem                           [SHELL32.112]
     532 */
     533ODINFUNCTION2(LRESULT, FileMenu_MeasureItem,
     534              HWND, hWnd,
     535              LPMEASUREITEMSTRUCT, lpmis)
     536{
     537   LPFMITEM pMyItem = (LPFMITEM)(lpmis->itemData);
     538   HDC hdc = GetDC(hWnd);
     539   SIZE size;
     540   LPFMINFO menuinfo;
     541
     542   TRACE("0x%08x %p %s\n", hWnd, lpmis, pMyItem->szItemText);
     543
     544   GetTextExtentPoint32A(hdc, pMyItem->szItemText, pMyItem->cchItemText, &size);
     545
     546   lpmis->itemWidth = size.cx + FM_LEFTBORDER + FM_ICON_SIZE + FM_SPACE1 + FM_SPACE2 + FM_RIGHTBORDER;
     547   lpmis->itemHeight = (size.cy > (FM_ICON_SIZE + FM_Y_SPACE)) ? size.cy : (FM_ICON_SIZE + FM_Y_SPACE);
     548
     549   /* add the menubitmap */
     550   menuinfo = FM_GetMenuInfo(pMyItem->hMenu);
     551   if (menuinfo->bIsMagic)
     552     lpmis->itemWidth += menuinfo->nBorderWidth;
     553
     554   TRACE("-- 0x%04x 0x%04x\n", lpmis->itemWidth, lpmis->itemHeight);
     555   ReleaseDC (hWnd, hdc);
     556   return 0;
     557}
     558/*************************************************************************
     559 * FileMenu_DrawItem                              [SHELL32.105]
     560 */
     561ODINFUNCTION2(LRESULT, FileMenu_DrawItem,
     562              HWND, hWnd,
     563              LPDRAWITEMSTRUCT, lpdis)
     564{
     565   LPFMITEM pMyItem = (LPFMITEM)(lpdis->itemData);
     566   COLORREF clrPrevText, clrPrevBkgnd;
     567   int xi,yi,xt,yt;
     568   HIMAGELIST hImageList;
     569   RECT TextRect, BorderRect;
     570   LPFMINFO menuinfo;
     571
     572   TRACE("0x%08x %p %s\n", hWnd, lpdis, pMyItem->szItemText);
     573
     574   if (lpdis->itemState & ODS_SELECTED)
     575   {
     576     clrPrevText = SetTextColor(lpdis->hDC, GetSysColor (COLOR_HIGHLIGHTTEXT));
     577     clrPrevBkgnd = SetBkColor(lpdis->hDC, GetSysColor (COLOR_HIGHLIGHT));
     578   }
     579   else
     580   {
     581     clrPrevText = SetTextColor(lpdis->hDC, GetSysColor (COLOR_MENUTEXT));
     582     clrPrevBkgnd = SetBkColor(lpdis->hDC, GetSysColor (COLOR_MENU));
     583   }
     584
     585   CopyRect(&TextRect, &(lpdis->rcItem));
     586
     587   /* add the menubitmap */
     588   menuinfo = FM_GetMenuInfo(pMyItem->hMenu);
     589   if (menuinfo->bIsMagic)
     590     TextRect.left += menuinfo->nBorderWidth;
     591
     592   BorderRect.right = menuinfo->nBorderWidth;
     593/* FillRect(lpdis->hDC, &BorderRect, CreateSolidBrush( menuinfo->crBorderColor));
    563594*/
    564         TextRect.left += FM_LEFTBORDER;
    565         xi = TextRect.left + FM_SPACE1;
    566         yi = TextRect.top + FM_Y_SPACE/2;
    567         TextRect.bottom -= FM_Y_SPACE/2;
    568 
    569         xt = xi + FM_ICON_SIZE + FM_SPACE2;
    570         yt = yi;
    571 
    572         ExtTextOutA (lpdis->hDC, xt , yt, ETO_OPAQUE, &TextRect, pMyItem->szItemText, pMyItem->cchItemText, NULL);
    573        
    574         Shell_GetImageList(0, &hImageList);
    575         pImageList_Draw(hImageList, pMyItem->iIconIndex, lpdis->hDC, xi, yi, ILD_NORMAL);
    576 
    577         TRACE("-- 0x%04x 0x%04x 0x%04x 0x%04x\n", TextRect.left, TextRect.top, TextRect.right, TextRect.bottom);
    578        
    579         SetTextColor(lpdis->hDC, clrPrevText);
    580         SetBkColor(lpdis->hDC, clrPrevBkgnd);
    581 
    582         return TRUE;
    583 }
    584 
    585 /*************************************************************************
    586  * FileMenu_InitMenuPopup                       [SHELL32.109]
     595   TextRect.left += FM_LEFTBORDER;
     596   xi = TextRect.left + FM_SPACE1;
     597   yi = TextRect.top + FM_Y_SPACE/2;
     598   TextRect.bottom -= FM_Y_SPACE/2;
     599
     600   xt = xi + FM_ICON_SIZE + FM_SPACE2;
     601   yt = yi;
     602
     603   ExtTextOutA (lpdis->hDC, xt , yt, ETO_OPAQUE, &TextRect, pMyItem->szItemText, pMyItem->cchItemText, NULL);
     604
     605   Shell_GetImageList(0, &hImageList);
     606   pImageList_Draw(hImageList, pMyItem->iIconIndex, lpdis->hDC, xi, yi, ILD_NORMAL);
     607
     608   TRACE("-- 0x%04x 0x%04x 0x%04x 0x%04x\n", TextRect.left, TextRect.top, TextRect.right, TextRect.bottom);
     609
     610   SetTextColor(lpdis->hDC, clrPrevText);
     611   SetBkColor(lpdis->hDC, clrPrevBkgnd);
     612
     613   return TRUE;
     614}
     615
     616/*************************************************************************
     617 * FileMenu_InitMenuPopup                      [SHELL32.109]
    587618 *
    588619 * NOTES
     
    591622 *
    592623 */
    593 BOOL WINAPI FileMenu_InitMenuPopup (HMENU hmenu)
    594 {
    595         FM_InitMenuPopup(hmenu, NULL);
    596         return TRUE;
    597 }
    598 
    599 /*************************************************************************
    600  * FileMenu_HandleMenuChar                      [SHELL32.108]
    601  */
    602 LRESULT WINAPI FileMenu_HandleMenuChar(
    603         HMENU   hMenu,
    604         WPARAM  wParam)
    605 {
    606         FIXME("0x%08x 0x%08x\n",hMenu,wParam);
    607         return 0;
    608 }
    609 
    610 /*************************************************************************
    611  * FileMenu_DeleteAllItems                      [SHELL32.104]
     624ODINFUNCTION1(BOOL, FileMenu_InitMenuPopup,
     625              HMENU, hmenu)
     626{
     627   FM_InitMenuPopup(hmenu, NULL);
     628   return TRUE;
     629}
     630
     631/*************************************************************************
     632 * FileMenu_HandleMenuChar                     [SHELL32.108]
     633 */
     634ODINFUNCTION2(LRESULT, FileMenu_HandleMenuChar,
     635              HMENU, hMenu,
     636              WPARAM, wParam)
     637{
     638   FIXME("0x%08x 0x%08x\n",hMenu,wParam);
     639   return 0;
     640}
     641
     642/*************************************************************************
     643 * FileMenu_DeleteAllItems                     [SHELL32.104]
    612644 *
    613645 * NOTES
    614646 *  exported by name
    615647 */
    616 BOOL WINAPI FileMenu_DeleteAllItems (HMENU hmenu)
    617 {       
    618         MENUITEMINFOA   mii;
    619         LPFMINFO        menudata;
    620 
    621         int i;
    622        
    623         TRACE("0x%08x\n", hmenu);
    624        
    625         ZeroMemory ( &mii, sizeof(MENUITEMINFOA));
    626         mii.cbSize = sizeof(MENUITEMINFOA);
    627         mii.fMask = MIIM_SUBMENU|MIIM_DATA;
    628 
    629         for (i = 0; i < GetMenuItemCount( hmenu ); i++)
    630         { GetMenuItemInfoA(hmenu, i, TRUE, &mii );
    631 
    632           if (mii.dwItemData)
    633             SHFree((LPFMINFO)mii.dwItemData);
    634 
    635           if (mii.hSubMenu)
    636             FileMenu_Destroy(mii.hSubMenu);
    637         }
    638        
    639         while (DeleteMenu (hmenu, 0, MF_BYPOSITION)){};
    640 
    641         menudata = FM_GetMenuInfo(hmenu);
    642        
    643         menudata->bInitialized = FALSE;
    644        
    645         return TRUE;
    646 }
    647 
    648 /*************************************************************************
    649  * FileMenu_DeleteItemByCmd                     [SHELL32.]
    650  *
    651  */
    652 BOOL WINAPI FileMenu_DeleteItemByCmd (HMENU hMenu, UINT uID)
    653 {
    654         MENUITEMINFOA mii;
    655 
    656         TRACE("0x%08x 0x%08x\n", hMenu, uID);
    657        
    658         ZeroMemory ( &mii, sizeof(MENUITEMINFOA));
    659         mii.cbSize = sizeof(MENUITEMINFOA);
    660         mii.fMask = MIIM_SUBMENU;
    661 
    662         GetMenuItemInfoA(hMenu, uID, FALSE, &mii );
    663         if ( mii.hSubMenu );
    664 
    665         DeleteMenu(hMenu, MF_BYCOMMAND, uID);
    666         return TRUE;
    667 }
    668 
    669 /*************************************************************************
    670  * FileMenu_DeleteItemByIndex                   [SHELL32.140]
    671  */
    672 BOOL WINAPI FileMenu_DeleteItemByIndex ( HMENU hMenu, UINT uPos)
    673 {
    674         MENUITEMINFOA mii;
    675 
    676         TRACE("0x%08x 0x%08x\n", hMenu, uPos);
    677 
    678         ZeroMemory ( &mii, sizeof(MENUITEMINFOA));
    679         mii.cbSize = sizeof(MENUITEMINFOA);
    680         mii.fMask = MIIM_SUBMENU;
    681 
    682         GetMenuItemInfoA(hMenu, uPos, TRUE, &mii );
    683         if ( mii.hSubMenu );
    684 
    685         DeleteMenu(hMenu, MF_BYPOSITION, uPos);
    686         return TRUE;
    687 }
    688 
    689 /*************************************************************************
    690  * FileMenu_DeleteItemByFirstID                 [SHELL32.141]
    691  */
    692 BOOL WINAPI FileMenu_DeleteItemByFirstID(
    693         HMENU   hMenu,
    694         UINT    uID)
    695 {
    696         TRACE("0x%08x 0x%08x\n", hMenu, uID);
    697         return 0;
    698 }
    699 
    700 /*************************************************************************
    701  * FileMenu_DeleteSeparator                     [SHELL32.142]
    702  */
    703 BOOL WINAPI FileMenu_DeleteSeparator(HMENU hMenu)
    704 {
    705         TRACE("0x%08x\n", hMenu);
    706         return 0;
    707 }
    708 
    709 /*************************************************************************
    710  * FileMenu_EnableItemByCmd                     [SHELL32.143]
    711  */
    712 BOOL WINAPI FileMenu_EnableItemByCmd(
    713         HMENU   hMenu,
    714         UINT    uID,
    715         BOOL    bEnable)
    716 {
    717         TRACE("0x%08x 0x%08x 0x%08x\n", hMenu, uID,bEnable);
    718         return 0;
    719 }
    720 
    721 /*************************************************************************
    722  * FileMenu_GetItemExtent                       [SHELL32.144]
     648ODINFUNCTION1(BOOL, FileMenu_DeleteAllItems,
     649              HMENU, hmenu)
     650{
     651   MENUITEMINFOA  mii;
     652   LPFMINFO menudata;
     653
     654   int i;
     655
     656   TRACE("0x%08x\n", hmenu);
     657
     658   ZeroMemory ( &mii, sizeof(MENUITEMINFOA));
     659   mii.cbSize = sizeof(MENUITEMINFOA);
     660   mii.fMask = MIIM_SUBMENU|MIIM_DATA;
     661
     662   for (i = 0; i < GetMenuItemCount( hmenu ); i++)
     663   { GetMenuItemInfoA(hmenu, i, TRUE, &mii );
     664
     665     if (mii.dwItemData)
     666       SHFree((LPFMINFO)mii.dwItemData);
     667
     668     if (mii.hSubMenu)
     669       FileMenu_Destroy(mii.hSubMenu);
     670   }
     671
     672   while (DeleteMenu (hmenu, 0, MF_BYPOSITION)){};
     673
     674   menudata = FM_GetMenuInfo(hmenu);
     675
     676   menudata->bInitialized = FALSE;
     677
     678   return TRUE;
     679}
     680
     681/*************************************************************************
     682 * FileMenu_DeleteItemByCmd                    [SHELL32.]
     683 *
     684 */
     685ODINFUNCTION2(BOOL, FileMenu_DeleteItemByCmd,
     686              HMENU, hMenu,
     687              UINT, uID)
     688{
     689   MENUITEMINFOA mii;
     690
     691   TRACE("0x%08x 0x%08x\n", hMenu, uID);
     692
     693   ZeroMemory ( &mii, sizeof(MENUITEMINFOA));
     694   mii.cbSize = sizeof(MENUITEMINFOA);
     695   mii.fMask = MIIM_SUBMENU;
     696
     697   GetMenuItemInfoA(hMenu, uID, FALSE, &mii );
     698   if ( mii.hSubMenu );
     699
     700   DeleteMenu(hMenu, MF_BYCOMMAND, uID);
     701   return TRUE;
     702}
     703
     704/*************************************************************************
     705 * FileMenu_DeleteItemByIndex                  [SHELL32.140]
     706 */
     707ODINFUNCTION2(BOOL, FileMenu_DeleteItemByIndex,
     708              HMENU, hMenu,
     709              UINT, uPos)
     710{
     711   MENUITEMINFOA mii;
     712
     713   TRACE("0x%08x 0x%08x\n", hMenu, uPos);
     714
     715   ZeroMemory ( &mii, sizeof(MENUITEMINFOA));
     716   mii.cbSize = sizeof(MENUITEMINFOA);
     717   mii.fMask = MIIM_SUBMENU;
     718
     719   GetMenuItemInfoA(hMenu, uPos, TRUE, &mii );
     720   if ( mii.hSubMenu );
     721
     722   DeleteMenu(hMenu, MF_BYPOSITION, uPos);
     723   return TRUE;
     724}
     725
     726/*************************************************************************
     727 * FileMenu_DeleteItemByFirstID                [SHELL32.141]
     728 */
     729ODINFUNCTION2(BOOL, FileMenu_DeleteItemByFirstID,
     730              HMENU, hMenu,
     731              UINT, uID)
     732{
     733   TRACE("0x%08x 0x%08x\n", hMenu, uID);
     734   return 0;
     735}
     736
     737/*************************************************************************
     738 * FileMenu_DeleteSeparator                    [SHELL32.142]
     739 */
     740ODINFUNCTION1(BOOL, FileMenu_DeleteSeparator,
     741              HMENU, hMenu)
     742{
     743   TRACE("0x%08x\n", hMenu);
     744   return 0;
     745}
     746
     747/*************************************************************************
     748 * FileMenu_EnableItemByCmd                    [SHELL32.143]
     749 */
     750ODINFUNCTION3(BOOL, FileMenu_EnableItemByCmd,
     751              HMENU, hMenu,
     752              UINT, uID,
     753              BOOL, bEnable)
     754{
     755   TRACE("0x%08x 0x%08x 0x%08x\n", hMenu, uID,bEnable);
     756   return 0;
     757}
     758
     759/*************************************************************************
     760 * FileMenu_GetItemExtent                      [SHELL32.144]
    723761 *
    724762 * NOTES
    725763 *  if the menu is to big, entrys are getting cut away!!
    726764 */
    727 DWORD WINAPI FileMenu_GetItemExtent (HMENU hMenu, UINT uPos)
    728 {       RECT rect;
    729        
    730         FIXME("0x%08x 0x%08x\n", hMenu, uPos);
    731 
    732         if (GetMenuItemRect(0, hMenu, uPos, &rect))
    733         { FIXME("0x%04x 0x%04x 0x%04x 0x%04x\n",
    734           rect.right, rect.left, rect.top, rect.bottom);
    735           return ((rect.right-rect.left)<<16) + (rect.top-rect.bottom);
    736         }
    737         return 0x00100010; /*fixme*/
    738 }
    739 
    740 /*************************************************************************
    741  * FileMenu_AbortInitMenu                       [SHELL32.120]
    742  *
    743  */
    744 void WINAPI FileMenu_AbortInitMenu (void)
    745 {       TRACE("\n");
    746         bAbortInit = TRUE;
    747 }
    748 
    749 /*************************************************************************
    750  * SHFind_InitMenuPopup                         [SHELL32.149]
     765ODINFUNCTION2(DWORD, FileMenu_GetItemExtent,
     766              HMENU, hMenu,
     767              UINT, uPos)
     768{  RECT rect;
     769
     770   FIXME("0x%08x 0x%08x\n", hMenu, uPos);
     771
     772   if (GetMenuItemRect(0, hMenu, uPos, &rect))
     773   { FIXME("0x%04x 0x%04x 0x%04x 0x%04x\n",
     774     rect.right, rect.left, rect.top, rect.bottom);
     775     return ((rect.right-rect.left)<<16) + (rect.top-rect.bottom);
     776   }
     777   return 0x00100010; /*fixme*/
     778}
     779
     780/*************************************************************************
     781 * FileMenu_AbortInitMenu                      [SHELL32.120]
     782 *
     783 */
     784ODINPROCEDURE0(FileMenu_AbortInitMenu)
     785{
     786   bAbortInit = TRUE;
     787}
     788
     789/*************************************************************************
     790 * SHFind_InitMenuPopup                           [SHELL32.149]
    751791 *
    752792 *
    753793 * PARAMETERS
    754  *  hMenu               [in] handel of menu previously created
    755  *  hWndParent  [in] parent window
    756  *  w                   [in] no pointer
    757  *  x                   [in] no pointer
    758  */
    759 HRESULT WINAPI SHFind_InitMenuPopup (HMENU hMenu, HWND hWndParent, DWORD w, DWORD x)
    760 {       FIXME("hmenu=0x%08x hwnd=0x%08x 0x%08lx 0x%08lx stub\n",
    761                 hMenu,hWndParent,w,x);
    762         return TRUE;
    763 }
    764 
    765 /*************************************************************************
    766  * Shell_MergeMenus                             [SHELL32.67]
     794 *  hMenu      [in] handel of menu previously created
     795 *  hWndParent [in] parent window
     796 *  w       [in] no pointer
     797 *  x       [in] no pointer
     798 */
     799ODINFUNCTION4(HRESULT, SHFind_InitMenuPopup,
     800              HMENU, hMenu,
     801              HWND, hWndParent,
     802              DWORD, w,
     803              DWORD, x)
     804{  FIXME("hmenu=0x%08x hwnd=0x%08x 0x%08lx 0x%08lx stub\n",
     805      hMenu,hWndParent,w,x);
     806   return TRUE;
     807}
     808
     809/*************************************************************************
     810 * Shell_MergeMenus                               [SHELL32.67]
    767811 *
    768812 */
    769813BOOL _SHIsMenuSeparator(HMENU hm, int i)
    770814{
    771         MENUITEMINFOA mii;
    772 
    773         mii.cbSize = sizeof(MENUITEMINFOA);
    774         mii.fMask = MIIM_TYPE;
    775         mii.cch = 0;    /* WARNING: We MUST initialize it to 0*/
    776         if (!GetMenuItemInfoA(hm, i, TRUE, &mii))
    777         {
    778           return(FALSE);
    779         }
    780 
    781         if (mii.fType & MFT_SEPARATOR)
    782         {
    783           return(TRUE);
    784         }
    785 
    786         return(FALSE);
    787 }
    788 
    789 HRESULT WINAPI Shell_MergeMenus (HMENU hmDst, HMENU hmSrc, UINT uInsert, UINT uIDAdjust, UINT uIDAdjustMax, ULONG uFlags)
    790 {       int             nItem;
    791         HMENU           hmSubMenu;
    792         BOOL            bAlreadySeparated;
    793         MENUITEMINFOA   miiSrc;
    794         char            szName[256];
    795         UINT            uTemp, uIDMax = uIDAdjust;
    796 
    797         TRACE("hmenu1=0x%04x hmenu2=0x%04x 0x%04x 0x%04x 0x%04x  0x%04lx\n",
    798                  hmDst, hmSrc, uInsert, uIDAdjust, uIDAdjustMax, uFlags);
    799 
    800         if (!hmDst || !hmSrc)
    801         { return uIDMax;
    802         }
    803 
    804         nItem = GetMenuItemCount(hmDst);
    805 
    806         if (uInsert >= (UINT)nItem)     /* insert position inside menu? */
    807         {
    808           uInsert = (UINT)nItem;        /* append on the end */
    809           bAlreadySeparated = TRUE;
    810         }
    811         else
    812         {
    813           bAlreadySeparated = _SHIsMenuSeparator(hmDst, uInsert);;
    814         }
    815 
    816         if ((uFlags & MM_ADDSEPARATOR) && !bAlreadySeparated)
    817         {
    818           /* Add a separator between the menus */
    819           InsertMenuA(hmDst, uInsert, MF_BYPOSITION | MF_SEPARATOR, 0, NULL);
    820           bAlreadySeparated = TRUE;
    821         }
    822 
    823 
    824         /* Go through the menu items and clone them*/
    825         for (nItem = GetMenuItemCount(hmSrc) - 1; nItem >= 0; nItem--)
    826         {
    827           miiSrc.cbSize = sizeof(MENUITEMINFOA);
    828           miiSrc.fMask =  MIIM_STATE | MIIM_ID | MIIM_SUBMENU | MIIM_CHECKMARKS | MIIM_TYPE | MIIM_DATA;
    829 
    830           /* We need to reset this every time through the loop in case menus DON'T have IDs*/
    831           miiSrc.fType = MFT_STRING;
    832           miiSrc.dwTypeData = szName;
    833           miiSrc.dwItemData = 0;
    834           miiSrc.cch = sizeof(szName);
    835 
    836           if (!GetMenuItemInfoA(hmSrc, nItem, TRUE, &miiSrc))
    837           {
    838             continue;
    839           }
    840 
    841 /*        TRACE("found menu=0x%04x %s id=0x%04x mask=0x%08x smenu=0x%04x\n", hmSrc, debugstr_a(miiSrc.dwTypeData), miiSrc.wID, miiSrc.fMask,  miiSrc.hSubMenu);
     815   MENUITEMINFOA mii;
     816
     817   mii.cbSize = sizeof(MENUITEMINFOA);
     818   mii.fMask = MIIM_TYPE;
     819   mii.cch = 0;    /* WARNING: We MUST initialize it to 0*/
     820   if (!GetMenuItemInfoA(hm, i, TRUE, &mii))
     821   {
     822     return(FALSE);
     823   }
     824
     825   if (mii.fType & MFT_SEPARATOR)
     826   {
     827     return(TRUE);
     828   }
     829
     830   return(FALSE);
     831}
     832
     833ODINFUNCTION6(HRESULT, Shell_MergeMenus,
     834              HMENU, hmDst,
     835              HMENU, hmSrc,
     836              UINT, uInsert,
     837              UINT, uIDAdjust,
     838              UINT, uIDAdjustMax,
     839              ULONG, uFlags)
     840{  int      nItem;
     841   HMENU    hmSubMenu;
     842   BOOL     bAlreadySeparated;
     843   MENUITEMINFOA  miiSrc;
     844   char     szName[256];
     845   UINT     uTemp, uIDMax = uIDAdjust;
     846
     847   TRACE("hmenu1=0x%04x hmenu2=0x%04x 0x%04x 0x%04x 0x%04x  0x%04lx\n",
     848       hmDst, hmSrc, uInsert, uIDAdjust, uIDAdjustMax, uFlags);
     849
     850   if (!hmDst || !hmSrc)
     851   { return uIDMax;
     852   }
     853
     854   nItem = GetMenuItemCount(hmDst);
     855
     856   if (uInsert >= (UINT)nItem)           /* insert position inside menu? */
     857   {
     858     uInsert = (UINT)nItem;              /* append on the end */
     859     bAlreadySeparated = TRUE;
     860   }
     861   else
     862   {
     863     bAlreadySeparated = _SHIsMenuSeparator(hmDst, uInsert);;
     864   }
     865
     866   if ((uFlags & MM_ADDSEPARATOR) && !bAlreadySeparated)
     867   {
     868     /* Add a separator between the menus */
     869     InsertMenuA(hmDst, uInsert, MF_BYPOSITION | MF_SEPARATOR, 0, NULL);
     870     bAlreadySeparated = TRUE;
     871   }
     872
     873
     874   /* Go through the menu items and clone them*/
     875   for (nItem = GetMenuItemCount(hmSrc) - 1; nItem >= 0; nItem--)
     876   {
     877     miiSrc.cbSize = sizeof(MENUITEMINFOA);
     878     miiSrc.fMask =  MIIM_STATE | MIIM_ID | MIIM_SUBMENU | MIIM_CHECKMARKS | MIIM_TYPE | MIIM_DATA;
     879
     880     /* We need to reset this every time through the loop in case menus DON'T have IDs*/
     881     miiSrc.fType = MFT_STRING;
     882     miiSrc.dwTypeData = szName;
     883     miiSrc.dwItemData = 0;
     884     miiSrc.cch = sizeof(szName);
     885
     886     if (!GetMenuItemInfoA(hmSrc, nItem, TRUE, &miiSrc))
     887     {
     888       continue;
     889     }
     890
     891/*   TRACE("found menu=0x%04x %s id=0x%04x mask=0x%08x smenu=0x%04x\n", hmSrc, debugstr_a(miiSrc.dwTypeData), miiSrc.wID, miiSrc.fMask,  miiSrc.hSubMenu);
    842892*/
    843           if (miiSrc.fType & MFT_SEPARATOR)
    844           {
    845             /* This is a separator; don't put two of them in a row */
    846             if (bAlreadySeparated)
    847               continue;
    848 
    849             bAlreadySeparated = TRUE;
    850           }
    851           else if (miiSrc.hSubMenu)
    852           {
    853             if (uFlags & MM_SUBMENUSHAVEIDS)
    854             {
    855               miiSrc.wID += uIDAdjust;                  /* add uIDAdjust to the ID */
    856 
    857               if (miiSrc.wID > uIDAdjustMax)            /* skip ID's higher uIDAdjustMax */
    858                 continue;
    859 
    860               if (uIDMax <= miiSrc.wID)                 /* remember the highest ID */
    861                 uIDMax = miiSrc.wID + 1;
    862             }
    863             else
    864             {
    865               miiSrc.fMask &= ~MIIM_ID;                 /* Don't set IDs for submenus that didn't have them already */
    866             }
    867             hmSubMenu = miiSrc.hSubMenu;
    868 
    869             miiSrc.hSubMenu = CreatePopupMenu();
    870 
    871             if (!miiSrc.hSubMenu) return(uIDMax);
    872 
    873             uTemp = Shell_MergeMenus(miiSrc.hSubMenu, hmSubMenu, 0, uIDAdjust, uIDAdjustMax, uFlags & MM_SUBMENUSHAVEIDS);
    874 
    875             if (uIDMax <= uTemp)
    876               uIDMax = uTemp;
    877 
    878             bAlreadySeparated = FALSE;
    879           }
    880           else                                          /* normal menu item */
    881           {
    882             miiSrc.wID += uIDAdjust;                    /* add uIDAdjust to the ID */
    883 
    884             if (miiSrc.wID > uIDAdjustMax)              /* skip ID's higher uIDAdjustMax */
    885               continue;
    886 
    887             if (uIDMax <= miiSrc.wID)                   /* remember the highest ID */
    888               uIDMax = miiSrc.wID + 1;
    889 
    890             bAlreadySeparated = FALSE;
    891           }
    892 
    893 /*        TRACE("inserting menu=0x%04x %s id=0x%04x mask=0x%08x smenu=0x%04x\n", hmDst, debugstr_a(miiSrc.dwTypeData), miiSrc.wID, miiSrc.fMask, miiSrc.hSubMenu);
     893     if (miiSrc.fType & MFT_SEPARATOR)
     894     {
     895       /* This is a separator; don't put two of them in a row */
     896       if (bAlreadySeparated)
     897         continue;
     898
     899       bAlreadySeparated = TRUE;
     900     }
     901     else if (miiSrc.hSubMenu)
     902     {
     903       if (uFlags & MM_SUBMENUSHAVEIDS)
     904       {
     905         miiSrc.wID += uIDAdjust;              /* add uIDAdjust to the ID */
     906
     907         if (miiSrc.wID > uIDAdjustMax)     /* skip ID's higher uIDAdjustMax */
     908           continue;
     909
     910         if (uIDMax <= miiSrc.wID)             /* remember the highest ID */
     911           uIDMax = miiSrc.wID + 1;
     912       }
     913       else
     914       {
     915         miiSrc.fMask &= ~MIIM_ID;             /* Don't set IDs for submenus that didn't have them already */
     916       }
     917       hmSubMenu = miiSrc.hSubMenu;
     918
     919       miiSrc.hSubMenu = CreatePopupMenu();
     920
     921       if (!miiSrc.hSubMenu) return(uIDMax);
     922
     923       uTemp = Shell_MergeMenus(miiSrc.hSubMenu, hmSubMenu, 0, uIDAdjust, uIDAdjustMax, uFlags & MM_SUBMENUSHAVEIDS);
     924
     925       if (uIDMax <= uTemp)
     926         uIDMax = uTemp;
     927
     928       bAlreadySeparated = FALSE;
     929     }
     930     else                                      /* normal menu item */
     931     {
     932       miiSrc.wID += uIDAdjust;                /* add uIDAdjust to the ID */
     933
     934       if (miiSrc.wID > uIDAdjustMax)       /* skip ID's higher uIDAdjustMax */
     935         continue;
     936
     937       if (uIDMax <= miiSrc.wID)               /* remember the highest ID */
     938         uIDMax = miiSrc.wID + 1;
     939
     940       bAlreadySeparated = FALSE;
     941     }
     942
     943/*   TRACE("inserting menu=0x%04x %s id=0x%04x mask=0x%08x smenu=0x%04x\n", hmDst, debugstr_a(miiSrc.dwTypeData), miiSrc.wID, miiSrc.fMask, miiSrc.hSubMenu);
    894944*/
    895           if (!InsertMenuItemA(hmDst, uInsert, TRUE, &miiSrc))
    896           {
    897             return(uIDMax);
    898           }
    899         }
    900 
    901         /* Ensure the correct number of separators at the beginning of the
    902         inserted menu items*/
    903         if (uInsert == 0)
    904         {
    905           if (bAlreadySeparated)
    906           {
    907             DeleteMenu(hmDst, uInsert, MF_BYPOSITION);
    908           }
    909         }
    910         else
    911         {
    912           if (_SHIsMenuSeparator(hmDst, uInsert-1))
    913           {
    914             if (bAlreadySeparated)
    915             {
    916               DeleteMenu(hmDst, uInsert, MF_BYPOSITION);
    917             }
    918           }
    919           else
    920           {
    921             if ((uFlags & MM_ADDSEPARATOR) && !bAlreadySeparated)
    922             {
    923               /* Add a separator between the menus*/
    924               InsertMenuA(hmDst, uInsert, MF_BYPOSITION | MF_SEPARATOR, 0, NULL);
    925             }
    926           }
    927         }
    928         return(uIDMax);
    929 }
    930 
     945     if (!InsertMenuItemA(hmDst, uInsert, TRUE, &miiSrc))
     946     {
     947       return(uIDMax);
     948     }
     949   }
     950
     951   /* Ensure the correct number of separators at the beginning of the
     952   inserted menu items*/
     953   if (uInsert == 0)
     954   {
     955     if (bAlreadySeparated)
     956     {
     957       DeleteMenu(hmDst, uInsert, MF_BYPOSITION);
     958     }
     959   }
     960   else
     961   {
     962     if (_SHIsMenuSeparator(hmDst, uInsert-1))
     963     {
     964       if (bAlreadySeparated)
     965       {
     966         DeleteMenu(hmDst, uInsert, MF_BYPOSITION);
     967       }
     968     }
     969     else
     970     {
     971       if ((uFlags & MM_ADDSEPARATOR) && !bAlreadySeparated)
     972       {
     973         /* Add a separator between the menus*/
     974         InsertMenuA(hmDst, uInsert, MF_BYPOSITION | MF_SEPARATOR, 0, NULL);
     975       }
     976     }
     977   }
     978   return(uIDMax);
     979}
     980
     981
Note: See TracChangeset for help on using the changeset viewer.