From e11f8fd7f2c26968ed1560d9c3b2ef27ff707093 Mon Sep 17 00:00:00 2001
From: Tom Yu
+Concepts: Identity
+
+
+We highly recommend interested developers to contact the netidmgr@secure-endpoints.com +mailing list. +
+`9A~t^vOrBu&~hN6Uw84ygW-4bWjh7M<4_ANe{kXls74?W-=Pe+Q+|t z56~xhc@rCB?xMat%M~5~Mo>QhrqCx{ZXX@k*c4*PeJ;z^8tkd{u znyT1gV txmm*9)m_Y 5KO0qaer`HjJ`lA15TlV0_rW7Z(U$AK2e& z8saFh4TMdxY=MdR@Zp2lykG(B)dj-Z+EN4s1&J}}%fsD8WTmHwVHz63#l=N ;yZuKv+*R64;K3hfz_mqhK@dUj sUZ#5spsiRKf5p3?ApvMCrKiKK2 zq7`W3>g+5m_4^A0eSHz*gmL {95oY8ur0^J)(mnvEZkPj z!kmVQlqf%OTwepUDn_05LK(K78T<-rO 8@K z_fRA0xuK`54S7ANJ|xT3KNGxS8dEQ#Ita7 za~1C@Ys68^ZC|vz1N669wMxJk5y#-`xaH|7jvhWNF1fjhGVoyxa3!TAh(J$2ao;ac zOjA=6haL7yHgRG?f^c(j6?s{?qByr$WG1AGo9-T ^t zTh^A=;!Rl%)=Gj%Nr)2Xon3@J)`7lOf8g{H4&di3tdmbzCo$l4Ys`K722I3h@a}PI zbCx)NG%EjPN~B+XOGEsvK8!nZ>^B`9o#`t=L$8O1hT3e*Et;w*u&P6?W_5XtNJ`Kd z+ZF{vZEX5(G-$P5VfXoTc-6})^;}OUU2Xs```UEP)hHc* Z)qs@wqU1w=5FD;!j`Qu0~u(sP)H@C!T4XCZI$8@$wbAO*j0d3lxp1kX0m@U!6 zt!{~l!@H{}37s;2pKH^)`IS~hMH_ZaeEaqu(L%SxHEW(dX?Ny_leyEUPq+ET(tVV6 zdESy4mv&`ZhY T12BVV|~G z=U*a %LO{l&h{8r0sXsxqxwQ`4%`qE;IwoiHDY z_j(n@yKAR?yWqa+eOhVMDR_0q42z6KsYPA`w@dFw= 2t~N*6sPQfr#0XSUm-Rhu!# zO*^d)zC3tvr|Pt{39+3A*0fr*h$zphy6FJpcO9!tO{-Q12M1r?(WzQ9t)1Gzf&E*h z;=Q(}U0PgR$7NMjbAvCxzr16I^gca4`R9(Qsi{QMRQeAqEgkm7Wv-@{Z0x^8+oEGf zyeGfeX3;I8CJdT3Vu@O;c6tAzRx_8Vsafr`vasvekvS}S(-ZmYWbJa3qE@BjXTB>i zeQL!8_&w34C+!BQOk1Lc_guf!d{`S(qc+-k)poM?ga%aP?Q;X>!?=J^tGsIYd(5)b zzq|u(00kbjk+-iX^ tRa~203O5e|kYdI%K$;Fo2I+4Z4T-A~x`~ z9zA*#KDjVahP?pmR2ViwTeUrOv9st8eFuXddLv!hC-^}|V!JKcL*}x+cY@B)gI;90 z?BnSMJ(VllH%Pj=J=#%)&$UkMXT8RH7y7~ja$Z+gSA2kuHG_P0f}SmduC|5`J`j5W zS65e20KH%j-ORGQ1u#TmA7Hc0K+@wH@Rjr4AO&)o<+&F21Fp~|YS4eYr>KFBVtwW8 z ?dmsml zgY~X9aI((R2F^NQbOF9H=%gB8`}g&43jC`nVDS&GUgO&?w=h+o+Ej1!TrR3PN^7NB zyZLK+_B7OOi|1CFCWE@^s;a74G+8~MdmoGTGj)~@G3snFw&jS9BUENs^wL?{rAHf! zWh2I!5AN8kg++^{{TolWn9^*-HyyhV>Da=e%Zf1z&2)z~)0j4~L-!%QEVRcgRI;#W zI6}YghOQmD_p%s1c}|1oqS1(TeJ4y>&|$Vk>rS(JtEi0oX5PH78Z=nY-eOSel|u(~ zY}Raq%2z7~4OO i{?P4gB{f$)Tql9D6tYmtT{wM9at Up7j^n~?JA|g-Bd}ZTMruC zO`YDodq=-GJHG ^)WB1}c%xj>}nUtd<{8|lQiM=97pkRt8{)1%-JdU!vWB7!0) zH8q? HYinl$o4Lk0QfAjvYNB4v3wQmLoAw zwLnsMVDRT3FUt)UWM#354(;7f_ilskq2Ux49!ZbFLMSEn0cCjoOghSfMghxY^&T`y ztt-aRl_r6HhN>zw4rvV1aNrt@c^SZTM(W37Q338Qsx$!k{gDP@%$#)4#*iM}NVlgJ zO&vCZuot1H=^6Aa=P5n#aibNB7ncCAJCIr W6mq{N6|dh#Tg*6a14-VMJZBj7hg-;;pfi07fJ3K<}cW&FUaqr!6l8uK{t zJOF?5cn0Em5YwHpcL#2?q1!`^hWG4EGluC(_;WL}s30$&!f(5i#av_Bwb7yuXV?#b z_%PBOBt-p60Th3ji)~ihXbZ4!-Mp2yZ`n>eZSCpoPp2s^ERy0MMbgu!@f2=lM(w~u zhU#h F&vP_^zf9QB8( zYtYD^nlycg4t@OikzmVH(X;226&p@l=FXyxGiT5N%Z P`ZY3LFx7%t 2V-7_NNbd7-j#*}yIzkTz} +kma0NWNx~M5DW3LQ^$_Hws#>JA$3JUBsL??V+Rh>?Q7@h*|R6Kcbqz*xHJb7)v=Z#izWd3gszZFz&{GO5eq`Y zF-FF%E5|+ryfU=A8VyrZr{Nks3GpyAs&{V^N=<1{LqTV@Eur6j`;DIGJ*Sd_Vk*hc zqGOovjnih(7US8pdiG2*orU>WWA*|2ZeH6zAo1GPM*3>!_8l_pxbL>zDZ_5>K>O_X z(t(}(=;%HN^0|G9o~C+JFW~R4)QG0^1a{C=A3QM*bR7%)%s(SlRUuD-7ubiXF`pwr z&Wu#=Ny9XHkxp+78q-sax(Frejl*&ts2=N!Re(F@(YGO?5 z=FFyVaNx6K_H5d?Y85S6xUdKd;3lwJA@x4!uusD8z%*yvJNMB3U3=-^o&%6chiLz9 z2Xa6A6Z!ewpcLN=G`@|Xah=-H1n|%p@bVbU!5GNaQMhv&fix6roAD3DdeH^1k5*SF zJ du(jz%K7um3n!3t;L8HP+y4>!?tOH4-vK(fe?NVD=n!PmMY?s#jr^}2 zqlDvjG`dAo8Uxx72VaboaI4a2jA1nX9?iTCtiv!iUaM-5pA8!}rhW|@l2!W_bamZK zdKT|aIk^#(kq}Oqi7`}|n?sM|lPNtumEbd@bH@(QrWw=7cK%%2WHN_V%$Y;WOiXCS z+_|)Jz6sfE*ieuE>`%YYe$afM{T@09x*u{lK#qG4(zp8$lH>kEbmG`|bo=^s^0{)E zZr(UYrMJH$hXFmIm#`ky)M$iS4;qcNFsi!>=nq~3=1~~iu&(OVs8I`Q)2I<0Fdax) z*B$ApuQR2k`BPGiFC{#Pq|~TrN_`YfIcaH-*U^yMF%
UUwmm64>`0lG1kvj?hu0(@v-8j;AO2UB60R zw|=Fn2WRN;Xie(Z32PD9M|9&cfbV-CVLZA$G-v?E(YSGA+Nj= Ka8dHN3jzA*szDtn-3{6B!aRY$B_A=d9-DYG4Ri&HS#&&ajaP| zkL)*ZuE+nYs~erc9P9(_kL;7t{9EAu{_wZ-{h_1e`tup`_x7fMTOQ k3sxyV0h8 z14y-t8tH+*NAcQ(OdO`s1M)=;dxmZj_6vJk?KB_&Y&gD^@AzC#JY_b4$ugpwja z`-hJx?NK~s#3sq`hei=%)F=_-dG(@zPHf#k>!(kLE|cM3H5atUe3&hmPrJXs?+*M| zFJ306?|#6VWqt?UF&`(sJqG-abou;63h?ovKrc@U4)vz0m@72CaWfjI)(bLRoksQ4 zfFA7y>>8xjS(#db?zb0C0B-2Nhu#zt^njwnLZJ`CDLx_sI{hIfKa8Qo=r~Gwlt`(u z$rApU&`659A4*S>A5&FDG2M3BPpc+RCUf9l3%WD@we#lDx`hjA*QU?(zXt3czg{Jr zKhU=a9f94EzB_V^et`b^4r94>?FQWg{`=myC^Ymg-Q2&1x;JS8-PwmmXsY85?7cLp zb?YuP3fQBMY@p<1@N!Hf#e@V=Joq9u0{fAN(ZKwOQh+@L*pp%sDJ3R}9>=9nPI?+W z0^fvT|5%b+K(ES6Dg4);Xw|f-WCs2>W4@n<`+|kEZm}s@tyoddKi4i@q3f5g(XA^t z$@%+}&{^No@x$NK502l_FHR@vKK67$K3;VH?q!O+dxoZWZcl0*AvZOlKQ(*N2<%}R zfR`4x_=>WfcT04S4iBTa&|s{`hm;Tv+)=Thc|33
L&?E4FSz!rP zz9^;G>t|@qjF}SeubXQ^Yaol(nJ%XJGiG3Kw5}fib$1W)yn2&-u6xmC*Gu4;W7s>K z0RCfi^}HJe-SMShKVOOryG^HU%?O()G8!;YqWe(n!G`wgNr+>kkWFhT1#2`i+yi_b zO39#mLPQ+s9!JTHJ32v1sld#M$H4eA )1UE6V~~$STD$VR z?36?*;Qd=p0n#&iQSyx3PdU Ubo%?_bi?gD#l{Ac z?}=SBNmrMaOac9Ydz_XgeXZG>Mr&wEc1^@d3#zLtr>de7dQ)0KZ_27DH}whjG%1wy zD1jbBM=|!tko5}LlZL-JFFPfZe*gFZ_;V=#Ne(@S4HI(Hot6Q&>8#o0uwn_7=cdyO z(7dFefL<0AQT2<@`0x3E?!EyO9B?20hx-(MKZvfoU80|%ql|q4 *HMiDSmo zlIe`UH+V;r^!sQ^`*^nP PcVs(V(yU^`cRb z|JcJ)rSCC%TUSf37=K9xy(_PxcQ0${-K*DBQTRfVi_9za_`y3&e@-cw9|?bY7G YC)=>8Ku{LzMH0l%T%WLk=d-SK@jX>@;eBrQ^JrAh{k1=UsOQEg=nu$NL@StY$K zuckWSe*^q)tLx}B<{~2@Ra(D12FA_wXWhlJ>3!X6?AbEmgLp!DxlifhF$YQZn1Ww} zpa)6|iwNi3RL1sAA?ROHR?q*Ta=I(9Bjy16ox8B%f1!(~exQg5Pm1*TkyefvN+WfK zLvLw81`VXqJ^M 5{Vx1q66fdio>E40NR**G(fBo%nX9v4s7sr9ReeHNAe8Mb)6o z>tbLp19rw=3EBfc)1UEwz<6pgwuFe7dfv%^?#fJfOc~H$N$_Lh%!ZO9@6*QlGie#@ z#l@2i=^pm%MUZQStQ(-;n2*ZPm%{#H?94N~|7P09MLnVikVTh%K1c3nT%i;Eu+IYi z%!lC5`;_WpLkEoqQna%bu$NM8X(82O&Aq|8t$p#5UQ27YR>EH=pM!V6{~mw8! y%8S5D9K!KmJ zM~7gq2>fxdDH5 J4fCnF(FI z$8sIbHJVKGf&YQeRVv6Ypn`1ZH@S{3hAdLxe*`@vVaI+Y0Xm=ewGsEi$^G1~u#+!Q zAoic>NuX773ijqnSVPaKte_C<=owWO7f~hTO-)H9)k5aKf!ujhUPE;ikUcNofac(v z%C|@|9^yHuE_o^OP)029$2|sJ9z%9!lDEe#3W5H~NK2=i=YJsM2@}Y~Xd-L^U+Cs% z&<)UU7(*fEp(y`(J^tA6XxMFRd&W`{^gY`Xv7ynhLEQ=GjO2&C(Gy_LhK-sFA0^93 zPSqtZs0O- >Yc QN8?q?}`i=E-KE}X%3
sWiRkz-*qM+U&w_mk|&tQ5%BjBIHh z@-T*HPxI>WCnrLugFn(z(N L0u}_c_`=}HN=i>C~<9qnDpP*gP^hqYLGi@`lSBD*S Ol+CH}L&oQXT*a)w;bxzfc87wPh^m+2bzogVI& zVb{BmxAzUY?c+mt{jkRi2qeS>!VV6FUW=fI4 L1 z<9OI;Nst}j0oKpi7zfXRf`1SK)9BL0i>F-Ao}-KBFVN*nkUN*LcCTF{PtO~KxHj_j z!5$lWAkaU69z4K)BP0YiSvVmsfudpG#>PT+B_v4rIY j)Kj=37F&M{)wbV;A_b4H0(VxQqp8&;CaAWP~gX1 zy1Z_98D4NbUwR39Pj}$wIk@3*ojh;CHui#j2D=~tXJq&9V~-siOo$7iNYIJrASNb; z;^X6CyJJtEk|NDP26U3dC)wH395DXp&!5-NK|#(Fsa{NY1ZW(O{Y@6t)<722)FMVJ zL()S@Y`ew4=49VuBKRA8^du!+ng@WE{GW38((V53+g;r+T@G~z4_$S?O4qRu^}KO| zyl;7t?`>c5XCAtD??25$JO_W~A>PlI7Ci?qXVA;CQmU>7_S#zLM(jJV7cYS=krbBz zK4O_J^RuKw4)R)fiaGd?@XN=d wP=k&(H4 ;DldeNkT>X*`mW z^cVj4-+BFa#) vik+=YBkqjv&oO>VZ_RFKoAML!6PN6le6~cPDT@5JS1J1M~9IXgFfjhPUlN z(-GS;xjV =zo(HD@iqwk5smO2nG|EQW1B76Bi7>(&RT=9muCIBLw^Ld1`TFuYM}qFm Tf2tvP5Vpq$?;cv zkR~H_*loW9@iDgKfEW{w(ct(Pd=Dh;<#R&adAZYY#8*t|i5R!8-AKP1$HV{w#>%lU zocO$M6yiv@e=a{+vkO&MRZDxv^9S~l^@0Utzut_j)|%1wO`AT>oiir|<#r?Wbv$%X zinGA)oX|n^dkE?1funTk+!<* ADltGe_u<-zwSlK&AyW2ltzOOq?iuG&kXL;m6|keE}hHI zY~6q^E*UG?Xl!RD!bZe*ayY|vL2SSRa#**Hwyj@J+s)UL{iaRz{a?J`N=I=%%`qCs zIJN;8I8N*i&c5#X`eLtIOc{rklUm~@;Bhq?quzzaAwEF6i!2^sWc%jy(DOL@g-y*i zI&8Ys2=;qDqIlT9Ia!HhiT-U@t)}f8){(9G2E@Hs)%Sn(>Qy=ie=v`o&&ZD nLR3D#CYqGz9TB`n`LRM(57bnD@-+Rc~7-M~5Q@Axw(>NXK3}7XHHw z(Bajq5<0SGDQ);>Iqg8-J1s5AX5HsFl^d|bZs45z M87Iyp2jEPpkHiCyPHvX`Cw#8JXQ_OKEgQS+ z+>XaymS0TIa}l!#ze+}G49!QZ!(7B`lxM|DwpdO1=X25k@EG%2@Vy6g6?*8x>7OYa z{j Aj1KD z5l^8h(IV)~R>`mT=0!DCJS#?=7S0C1bJE!je9TM}_GLfIeJ1tq?sSxvBfcg%;*P`% zii4J _^k zFRm1bb3*oU<>qFP)8c-F&65;sT~!_`+3s)Q v7V#QyQ;- zoUdnQJf=0qGiesiY?5L_B_G*yoYj;R6!EwuKUYjN{G2!^V1H6nP&oa1&W-N-_)!LY z8GJs%zNh@4pQtu3RN}ig;H|eW(ErP7+1U{=yhs1F@Lls6w(R`nG2OxWe{xbHo!Dnb zGiT1El!S+puk?8i{H6Jy&spN(SCry#fH^KahOW56H|}u@zWr4A#-C6XpPRsE!G4z- z@SJpx1)uo4O7`c!md;YxpI=k@QtCfl?z_K@xRn^h;0617kO|I+v$Nr6hri|-;uya4 z)2Ak5zTkt(Oist#Jtluo_>ykj#hFMJ&J}TXiL;xxW$?k5^SKB2_lAC}!PyP^{H^+f zELFXi&JP|#2J$%t``+1a9SAv=nh-~ig09K@)bQ_eJaWMoe)gdIL6YAm8~#l8mnr-= z{5Sh<{@KL72KG^~zlddr*L6?2e(5U3AYMETzTb5Cc(T&iuMR(X)@MKeg|ioCopL() z%H ;;y6uhl6UZm_3$j0l{ZZ@-VP7EYTK2^ {lxI0H@|f0k{|nrJ>Xka^v!-@Mc)d4F#F@# zhotbu^I1f_55BmNGSlFb#yQQ)7sV3a6crXpe(MBa;J6C~1_l4)E?s-}>}lY2(`)5b z_D^5GPTufMvtN|`y6jhHpR|Iud>)|irPq&N?n7r8qwpKDzmR=XyoS;czn6r)eG2yY z_?EwZ{VDoa-18pisocDNJ&S#t>=$IeEc?Y3=Mp@}U(%n?BJ$wJSNNV3{WIUN-<2`2 zkBt3H97B?T^_GmY6ZH3Y{bXpbnXk96%b(|;X~6T(XA0~GV;ZoWVjm>y8a@Y6_#T;m zxqluzuU*E#=RCYG#&1h-|9|P{!k8PuZ^ri0|I-({3^2fPNIj6)F8hOhi06OFwHK{~ zAhBQL9nx=dUj-Y+i1m>?6#u|a!MNC0& }h*f7@+q^*o!gt0MsCO2L?N!Z9 zn>OXFUAY?Hf!IoG((A?rYKF3Uu)#;bE^VtMdE01wuTGSnmLU0lAsc?fw+(KnKhDn1 zE@#We&9uvQ2V&?CNpk*>(Libsy9)2Adut^sN(+ U>YqJ(Hs}1$XQjGl4@vf))c@kiL#45DEYpXY zcl4s51o6a(LxF5zy@GK|_3>LNIUa}!zH{r2B#*bRok3to&>>wK`y1>DKGwdM;%L|& zVj0DLl-;{`OZC0Hys~| jGvhjA^$$*?=K|I9hxcfRv| zKQ~U@ILR_h3UiRj$Vg?#!9B+?1^7-)rT3XB43qObgLSgXFwKV;=Gy~go!%F|z%Vbp zn6!SFVXhrXTF0}mz05F~csv7t$MKiK;K$vgolQG(D4pINmVS6JmXe;I_vz)blAo^r zSpVlOxlB4cJ!LVQ!{JbsGA%v-{Ab^km;HS0>YcjV@~+O=nQ5y9YvC&8(W4j6ee!i_ zaq@dsiv?@j+uPNqw6yfg<)z6l+N_pnB!a~%Wjg!JyHgY62EEShb`K8?b}Qs6<-E)3 zOvK|f&I<@I32SO{V%4DccszIO>w0?>YL&|EcExue-g)J}u>n@Iyu@+b
G8j;K{igF$aGvnD6UA>Dlme*5LR 1RA44p zhW;Ytw?UT>x`_T)!` =f=iHlVJrAh{O_=aD%i6 zhrmkK5()gixw*L){b8#Fc|c6aLkSRlR#p~r$}O)rTTonETbmpxZ~*IexxDM^KA(^1 z7Y-Bs1PYcaBgRhAWu4Ob`B{+wH0K9+N`_DHT`Ver074QZfoL?saSnLX>s^PuaKlcG z5(&t@7hEClLT3?tsy{&ADE$89=OuuqG*GXlr9~tFoPBK#R)rH$X}{ke63P^h#r8$- z>+M-ktHcCQf|{BdgaryQjmpZ(M1tKhY9tc2S}ky&)5*crJWt#N4rE4)Dhh+xfj;oK zAI&BbAntojO>kmvd1W#I>PQ;_#Wk6XFu22RM?Yg`phW|L01LapGJDaV4i3Kg{s*ES z0L^?mr>Lk%wAG30Z4!w@Kqn #d~{?u>x-}c)nAO7 zUO=&TvvNfJ;Y1MVR#sM54Q4YqY@EX(dJ2AoV?<#PI?yM^$1Ywf{B~QLbGFer4 MG_wCYR``ebJ| @;sbqaYYSserBuQeTCGN}*O`n)Y(vyi6XT {Kq zik+Xs#75 q@$)Rg0Ju-lI3 _r-DFTK z dgdmG)dpcp)b{R6uv1VdORl+e5*7>q)9BNPjLwYx V6uvrV{NXldW@47b)XXgYT0-`7aT>Q^CPX(kb w6suY`6{Sq=e)NUTLnnol-|DgJkNQ~ zbI$u-+IQ(7&v9$G^_)Vn2|w3y&b1sD$8p@IP15(BYdG$}D;)k#`!;a-8#wN#b@aRR zJ^odW+xD9LyMoKd=NC82zbm+S-248!9Jdo=VhC;zF2Y&*E8(|nUZW`6{(8<@MQqIR zh;u1tQ+~VftNQxiSJj$|GId9Lo7!%(DQ9M;kEZM2QN*77CgR7`l$75uUQpl2zNXex zma97+x2r`v?U~u1uHUia^og(4KO`p!7)QW30>%+Ajv(6Y0`3t2AR=AAb;s$L IxqH0uT|=5Dv!ZEdKpyLex#NigVjr^Z~a z$b~@QZ8^c^FxpyMbk+e&x5wkL=3LKCsIJl`7!8J_ZueMZAP{&{emD5ZbITDxP)Bc1 zx5MdlIvzf#{s#%Dj0U|538;`jf*fQy0*wui9DTh#4&3WN0xBe+GIbeMNI iZfI*^Aw#F45fI=NlOr_IbTtUteFZ4p$?7Z=Cdc8?jpD z #sX92T<#YI|+@Z`x8w&)qXi?NNJ z9gp*uQ-BEY8R>sQraA*EE6TuRG{Uebg2OQawxL0YJah~`h~vZ7d(kIBqtU=5g8Qb3 zpr4VLpPvUT4I?u*HwV+xesDQQVFDAPeVB~P@AGLwOMuu42A*{}6SA*m0m=oXCB@L% zA}|Gxq$o4CE4J`jtu_eegPG}R21p A7VulQW6mgG@!NmADmS<8b z4JyJ)6C@$49GbZdUQu2KI$cK?0U~meuk|iTLJx@5nZ&b9`k=%?0<+-6nq#YB-N#u8 z$*^QnnFN)1C2*~#5^&DEM1cP={ukJH>MR46rJ*_%6chyAFFBup93vxWJSXcYGT#)M zZ#w9i0QzM$@S5r>=rS6@2%rae$jr=SZAT mZj4NnqQ0y;27d ziMhGiCBucvPMH&U?ZXFv^Cyfz^cB7qZsp~%mO7G}_7Z_b*8h?M)B!`-y41#_4hP^A zL=rexaHjZtQumPCR|0=jR|mWHe-@^69FLjq+ 4&Lkwkm&rfF;pFphIORMXj7@@%KaGZuVv<=Y zcE=?1pj0ZKg9k?~BY+O??dbutxgQ3tR=^V-@T>^ygw?>?+gf43Vv)u_dSz+~TNhPg zrlo<#W(hA%y3lqba9T8iO V06fN} zM3|bAuP_de* ozC4wcj?zIL3p` cyR$N0qX+1AE1f5v6K23=^^qE8kw~)mVm~(d=DX?&^&p5N5Ml6 W@!08$UZKk5e!hNf+1+iM hGZu{BxpPH(#WcozW-#!H%h*9BV-YinFWS$3i?RFf zG2zc u2Ccy`f*)!} z#=}dAM$iV#a71vh)Qh${5}L6_DLvq0)!GPS+W@9kO(bEcwOR;3BU*HTt&NF=*0Z9G zrZxr|+Sq^JenuMuvjzhhA$efLs-y8PwP7vz85q<;fcV@Q;zK}gbJ=) P#fWfKi7ez( 6A4kCG}! zqt+^8)xlcrW~~xM5s9Y~V@*$`_7!T!KC6v=2GtWwgQDK09R~h(g O(v&h^Gkgq#>4Z9zz0Rh+-k|I|cq`rl+$5NlC06zIMaU zT==PjpFWAXtPp;V!OuGQHw6DW;9n{H^Yjg11@JG2`xnF9L!y`${F|bw41Ap#2>l 7Eb>*&OKVI?I~)h>$#7AhDet zJ;}tj&G2#|=Su=Y+nM-Wz{q#8vqM^}tT?!{v*j8fyE1aZjpHlrNWj*LY=dpN2y74p z9^?KgB>{=O^1)@xmOb*=Z1R%x9Z3K_3hkBlN*)g!76Mj|HbQ`due2vVr4|uO`jS8> z3|KhNvz)Hv7J(>$oRkni5E!CWKeP6Bu(Wq14fK#z%AKtpX^1kicAaNGoeO|Zfs+8L z!N?B{g%L|fI89;6MgSu8zqzOR`HI@#+<8tqr_kBNNYXjQartV#Uj_vQ@V(j7(}TH( z$ML<~dA$ce!_XNZA|iq<_wwWC6Bl<+zOU1{!X5i5?Z*iT3Ct@dnV%EZuV2s41kS71 zGj}g kfP$wiZ~ve*XN-6Nj@?)`<*blvBS`8JNnzT{1A; zjBH#LoF1?dguTO!$kkHNLaAfsLP5?ec*ngfoCVq1DyV}I$UV-swo8^M+>97*YiyUy zo~;0wtLxIGg!=Go7Z 5l7P}{=6#) ;KIAUrw7Av>sD7!cXxK?ark+$;5_Ws*4F468`|625bUJ*e~x=SHRYol<=4A9 zJB2!+diDCgzTW=+zK)LeuCC5rea}FDKQ4gl^*#7Z0{3p;#&!EMPG~|HAXke%HS-_% zZ~i6zt-Wt%W*obI?OJnFQ%lQDd^q; mvR6A@tg(IWsCgiq5lZT(wbc6K%g?;9K#06t)0 z0^^7X5D1D5B_w)ybhiZyp3C6>cz^%F %a$#EVK4gadhyBNP<$pc^%FRN?d<62zI98l z*HiWe2Pu2pgh-3*xd6{Neyq5-NR9$8a-#48b5DotMEE=e8sg#Mp|-YGlx27KEz|}o zK^ma3G30zAcy?AM<`f1OXtI^>Z{G=IVQ6FYzC(u&$@oBPxp@;+iXy})_xAP<@G%-4 z8JQIP)XAK(Yo!9;%!I(l^QD(wGQl5gYSN+b+S}Vu&pka _ guZcx;kteSg+)AniTxX<-*#U8d{EePz-v6N%dfyKB!EX z5SfSbAk_Tzva*Vb8#UF{_4Rc+U87u16FmnwmMM5b^994i7aXxBj0_Ktj$-1B%9#f^ z{yM|rR$5YmlBle#sHv%LsISNNB+BX1#e(DMA7`W=&Cbj?m6M(K$*Hra^9# *LbtJ8AXCp#~|M7!i2)I(1SUJG~xy0 zix6Oo%BiVI;EN~lvCDjXI293{J)L*;(<>##S25ABuye1fku -2r2p-0%%7&2K{xy{y}z`3`Ou(&=Ktd}F; _Te$i{k_MN{DdB}a^l68-oUFZaB;-!A>IV?)~6X-kc?qE&4 E^rzQe6O#Mi+lLEWGZi!U zoF3Ycuy-#c52d8wf; *F&@&Et; literal 0 HcmV?d00001 diff --git a/src/windows/identity/ui/images/cfg_plugin_err.ico b/src/windows/identity/ui/images/cfg_plugin_err.ico new file mode 100644 index 0000000000000000000000000000000000000000..1b1b4ee2e2046f33094256112192ae392f5bd9f6 GIT binary patch literal 8854 zcmeHM3sh9c86K6e>n;I#7y&WrCVC9M5-XlaPQYS94Op5(8&YWnB|U_ab+NPoVidP& zgSRGyHmR7B6r*W~L4=6%2pYr}DiQ=l dCB{2!uFe)yPM16u}RZ5r>FePy?6fk z|M}+s|M}<6?1hkN#GEWxFpE%XolZzFp0j3ge#taKd}a{Hsg#hzazY}^sGRd5_Yv~o z{SvtaAu%=*Ir^@cPskFeFTk}9*E9kE6B6NAtCrqz(~1?X$Y{}!mzPKMRF0cotms8X z&l{-p-$;=H1CvE**)uXypu@@{qvCpK1Nb;C;{_ux#8J60j20nE5cGmxKY|D4qvBwt zNF(3@qmKv<7F)riAxhX|(CPua5Ftbucs*c+7$Gt;QpA85yddn^%^M&F9}_8ra2_nx z9~SmV`KSr}i$Y9<5T)1CL8v~(pm;Ew@fa=mMOudfl^cwKOD24rUQQKgN6-i~32zX) zu+T{~_=M30111gWw;?|A#CwmvQJ?3o-JLfd*9@%;_|gj*{`E-<)dpN&;G%gjaU{K- z<~hyf1-Sl`d5$?@v>oHfP}`0evL}* 3N8t`R zCXN36ek4SY?+Ib@kUdmg& 6 V^K0l8fyCnu8x1^AP?x+>xpok;TY&yt~`KH?UjA%_knlGM~x z@>Xmt@ekIJs;Y9**Vjc_T6CnSsDLc?2_R?B=8}Yj1TsE8Mlv(gNqKoWiH?pYU0q#7 zr_+&wf&$_d98QvxlZls?7s<`dC1Yb_BtHHv;-}dG{Zi<*qdkWNg@&R}9s1;xq@*O0 zo}Nk)6BCG=moMxtC4S-2u)7^L=fK`N;u)I?d-GxM5b+7pkZ=vPu?jZ!!NwNYSVTO1 z{bA!-*p^B5#=J&W1xFJPFCW+(Pa+V9;G%K(A3!|OKk3jRl1}}7D;BnBNFwuVoK(T5 zKKRoDe~REwDtsAdKE%U^Xc7v$lVNXWdOA6jm`KWDYZvUyg`GOs>64I43Sj3L?5u-* zL$I$M_Lagu58nWi5BqYMeKEu}G@5wAK0C(>$s|ryry}s}BB1^spzqIdu#=c+!phdt z23w`5A)7IQRjavN?xf%fTrPJq0y4S6(M)CTNE?}4VeRD4S#!l4OLIF%xvi76wXKuV z$;rW70nW@Ix3Y9}0@)}bqBk3*JtL)~9fPy-e%L{+wsm&%0L^xQ3RO@l&74rfaNZ9; zHAk&pYO{#i6KIY`rT`5FqlVaj*)mIqM`l9qrVyJc0#~47wc2vIod@I#7cH7KhY!!J zL6!DatCu@Wr}F!71wKL*Fg`Wc-kyT1)ec-9x*<@lo@q(t@Q_+)4>6Ui9BKcDl^bxM z%jBX0#LLxc6_+nlK4y?R+u9;5N+rbbU!_ L)3Zj_GX=r)SXn#=w zp>Z%*J)oE_XCnfU13Af|04HG6vY%RdIVkK{546xxY3yulX%B9+;vYri+lwajJl9 zFvt->bCtpoMpL(pg8+p0|L*RFbBFZ#-JR#ea|%717)U&)I4)kn_RFB40Jb-Kc(@VQ z@L0B&tJb)&GYmZgL_|c8#h!lbeB$it!S;1}u5iVEO84XV_;}(Olf=#mYu2n`X9CrV zHN@4^i=9#Ex#YFiqKPv-!{AJ^!p)O-`T7wJ&Jgt66T5dWS>@_Rf`WqB*@K>y=$U56 zjvd6=%b%Sm#>dBr24lIpy0Sg}!Bwun_aUo*2fLZ`nfY^+GMRFf`OKLQd_}D8Vl{zW?h%@QDw_Oz(4P0fx1=fhe~ds- zz|VdiwoQ2bcL)CVZdS(eqQWb>#>T ?;BsAUO=oB4!2^jWbF#0MmUeWsj~bNkiVxU|8|AI7t+}6_ z1pc+sl6&A^IDfXX;sz8r{`InJz^6wLMyEc_zIgsz;=AvpBp*KcX%>trzg|{dReAGf zb9Z-lWn~2l>OI}vn2y`GJG;BOvNKP>&P(|hFm7#ajjpkwt+f@--WC5(v2Ug%e|)3- zdS^!m?+&Qmo}RwG-v0i+_V%{U&W_%m?t%V(6oB{ibmKD#%)4_3<<1w3z(N@ySBpM3 zu^;$v|2b~|zPB?oj^leVsHNp*V?({C@22ks?>3gj8w0blvH;%Ki*frg#K_19W(3H? z!@~mu{cWwcaBPB<8rIimj1LD-cxOM5`A29}V8373PR{cC#=oA<&dz4weS-r7zy~ab zz&yeOID%wD3h@@^-5oB1 BrI#Nd(7;@9pgkkNmdp+!U rlj~!ghc;f%QoXE2;Gq*M~wJDYq@z7S&AgY zEcf>I4zM{I9T`Db0DdI-uoVB)$(*ulrBeL;`}e~t=@7ei?ULXRHZ|#xcx`R1$mi~E znn)M|esOTbT#A1>_cN?ADgH-ENk~G!?YoRF03VacmjGtAp`pIHsp(cr3l=io6 9m^XhY9ul^`Vz5bbv_|l7rxd&)=?%XMYv-bnV@9(d; zaihArs=lrc8wcK3#&qJ~m{7zVLx2EYc%`7WriQ+bx{(Y$aFgbPVfjci6W}1^{PnW3 zii#UG)z$U&bvj+6F`ZyJ2S>~i77mWZ1xx69!8EZK4u2<%3=fZvV&RM$BM)%=I>XDY zw4?+nQCV40Q&ZhgUytpHr_<$2`6tpp$w)tzotbeeC;Rkgr_P CC(wH@- z+(;)5>DSsy->67(<{DNjA0751ZE9<4%FC};RaU@vq*D`1C%y}O@P1;_2M0g?=)
z?$uNL7APpzVk)9ItVbd5Kgn~@|)bxh*zPAn+A7P_&f5Jprmziz1G`fnT?5-Lmba&_`X}7p{KNq@WR^$tCjTm!H7r8^a6SSV1F1lgn?lyVtFAH>w#c zXoP5Td2{dHS6_L>W%X*KCMsaj2+`yczwa+7FkY%Zckwc*J4@HD`{NsLaLt47A3!nD zm-gj#r$^Vu@7o8>Bgx4qCi>V}um!9QkCS$M% KRO9TwL7KF&`Pb zKnI$6r%$7p=!4bk$5Ev1s6(^h@?{ihI{;U@dqO!aEzS9vO;UVlmX(!Z!*%}QW@9@l z*pb)z21@sRG(P_HMkwRe7Zw&KRlaK-29%T(L%FT3ZG-RgV5Q}um8 h!a`_*@Xo}0^Bx6fZ>f|YJa9JnIs|2tA8{IRZ1ZXp z^P2IIsHw)Wf@q;qF_fr85)E2v5ftjet=nHG%FLqiA1HqCJD1CMzH_*@tl~P`aHA5n zK2>?7@=ztq@I YDah>#Cd(XdKB9YKNt!GrU(Pj_QD9%zV z$aIgr*LxaF0{NW|9vkg9yc)3Ro|d0 $v(Q3A5 }oIj*gI-tlNCC})*Gylos$09AF zoLnI%F0sZgc>Dc~?u}ELloP5Jj(F~kQTW 7FeNN LVAWTAmR1}h$yT2j$n8h!Qo-l=4Qz1Mhb;>Py7G-e*OhgI1!5g diff --git a/src/windows/identity/ui/khmapp.h b/src/windows/identity/ui/khmapp.h index 7f12c7ffa..203f5b02b 100644 --- a/src/windows/identity/ui/khmapp.h +++ b/src/windows/identity/ui/khmapp.h @@ -36,6 +36,7 @@ #define KHERR_HMODULE khm_hInstance #define KHERR_FACILITY khm_facility #define KHERR_FACILITY_ID 3 +#define NOEXPORT #include #include @@ -63,6 +64,7 @@ #include #include #include +#include #include #include diff --git a/src/windows/identity/ui/lang/en_us/khapp.rc b/src/windows/identity/ui/lang/en_us/khapp.rc index b139effdb..0a746199b 100644 --- a/src/windows/identity/ui/lang/en_us/khapp.rc +++ b/src/windows/identity/ui/lang/en_us/khapp.rc @@ -68,6 +68,9 @@ IDI_ID ICON "..\\..\\images\\id.ico" IDI_APPICON_WARN ICON "..\\..\\images\\app_state_warn.ico" IDI_APPICON_EXP ICON "..\\..\\images\\app_state_exp.ico" IDI_APPICON_OK ICON "..\\..\\images\\app_state_ok.ico" +IDI_CFG_PLUGIN ICON "..\\..\\images\\cfg_plugin.ico" +IDI_CFG_PLUGIN_ERR ICON "..\\..\\images\\cfg_plugin_err.ico" +IDI_CFG_PLUGIN_DIS ICON "..\\..\\images\\cfg_plugin_dis.ico" ///////////////////////////////////////////////////////////////////////////// // @@ -245,14 +248,13 @@ FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN LTEXT "Title",IDC_CFG_TITLE,0,0,357,20,SS_CENTERIMAGE CONTROL "",IDC_CFG_NODELIST,"SysTreeView32",TVS_HASBUTTONS | - TVS_HASLINES | TVS_LINESATROOT | WS_TABSTOP,0,20,100,182 + TVS_HASLINES | TVS_LINESATROOT | TVS_TRACKSELECT | + WS_TABSTOP | 0x800,0,20,100,182 LTEXT "Static",IDC_CFG_PANE,102,20,255,182,NOT WS_VISIBLE | WS_BORDER PUSHBUTTON "&Ok",IDOK,162,205,78,16 PUSHBUTTON "&Cancel",IDCANCEL,246,205,51,16 PUSHBUTTON "&Apply",IDAPPLY,303,205,51,16,WS_DISABLED - PUSHBUTTON "C&hange Summary ...",IDC_CFG_SUMMARY,3,205,76,16, - WS_DISABLED END IDD_CFG_GENERIC DIALOGEX 0, 0, 255, 182 @@ -267,22 +269,29 @@ IDD_CFG_GENERAL DIALOGEX 0, 0, 255, 182 STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_SYSMENU FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN - GROUPBOX "Startup",IDC_CFG_STARTUP_GROUP,7,7,241,50 + GROUPBOX "Startup / Shutdown",IDC_CFG_STARTUP_GROUP,7,7,241,50 CONTROL "&Obtain new credentials at startup (if none are present)", IDC_CFG_AUTOINIT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, 16,22,196,10 + CONTROL "&Destroy all credentials on exit",IDC_CFG_DESTROYALL, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,16,39,111,10 CONTROL "&Start NetIDMgr during Windows logon",IDC_CFG_AUTOSTART, - "Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,16, - 38,135,10 - GROUPBOX "Other",IDC_CFG_OTHER,7,63,241,54 + "Button",BS_AUTOCHECKBOX | NOT WS_VISIBLE | WS_DISABLED | + WS_TABSTOP,16,48,135,10 + GROUPBOX "Other",IDC_CFG_OTHER,7,63,241,85 CONTROL "&Run NetIDMgr in system tray after window close", IDC_CFG_KEEPRUNNING,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,16,78,170,10 CONTROL "Monitor network connectivity",IDC_CFG_NETDETECT,"Button", BS_AUTOCHECKBOX | WS_TABSTOP,16,96,106,10 + CONTROL "Log trace events to trace log at the following location:", + IDC_CFG_LOGTOFILE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, + 16,113,225,10 + EDITTEXT IDC_CFG_LOGPATH,16,127,225,14,ES_AUTOHSCROLL | + ES_READONLY CONTROL "A&utomatically import Windows logon identity", IDC_CFG_AUTOIMPORT,"Button",BS_AUTOCHECKBOX | NOT - WS_VISIBLE | WS_TABSTOP,16,147,165,10 + WS_VISIBLE | WS_TABSTOP,16,158,165,10 END IDD_CFG_IDENTITIES DIALOGEX 0, 0, 255, 182 @@ -300,45 +309,55 @@ STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_SYSMENU EXSTYLE WS_EX_CONTROLPARENT FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN - CONTROL "&Monitor credential expiration",IDC_NOTIF_MONITOR, - "Button",BS_AUTOCHECKBOX | NOT WS_VISIBLE | WS_TABSTOP,7, - 111,139,10 CONTROL "&Renew automatically at",IDC_NOTIF_RENEW,"Button", BS_AUTOCHECKBOX | WS_TABSTOP,7,9,100,10 EDITTEXT IDC_NOTIF_RENEW_THR,122,7,126,14,ES_AUTOHSCROLL + CONTROL "Renew at &half life intervals when possible", + IDC_NOTIF_HALFLIFE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, + 48,27,148,10 CONTROL "Initial warning at",IDC_NOTIF_WARN1,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,7,31,100,10 - EDITTEXT IDC_NOTIF_WARN1_THR,122,29,126,14,ES_AUTOHSCROLL + BS_AUTOCHECKBOX | WS_TABSTOP,7,46,100,10 + EDITTEXT IDC_NOTIF_WARN1_THR,122,44,126,14,ES_AUTOHSCROLL CONTROL "Final warning at",IDC_NOTIF_WARN2,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,7,53,100,10 - EDITTEXT IDC_NOTIF_WARN2_THR,122,51,126,14,ES_AUTOHSCROLL + BS_AUTOCHECKBOX | WS_TABSTOP,7,68,100,10 + EDITTEXT IDC_NOTIF_WARN2_THR,122,66,126,14,ES_AUTOHSCROLL + CONTROL "&Monitor credential expiration",IDC_NOTIF_MONITOR, + "Button",BS_AUTOCHECKBOX | NOT WS_VISIBLE | WS_TABSTOP,7, + 103,139,10 END IDD_CFG_PLUGINS DIALOGEX 0, 0, 255, 182 STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_SYSMENU +EXSTYLE WS_EX_CONTROLPARENT FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN CONTROL "",IDC_CFG_PLUGINS,"SysListView32",LVS_REPORT | - LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,7,7,75,168 - GROUPBOX "Plugin",IDC_CFG_PLUGINGRP,86,7,162,103 - LTEXT "Description",IDC_CFG_LBL_DESC,90,20,36,8 - EDITTEXT IDC_CFG_DESC,134,17,109,14,ES_AUTOHSCROLL | ES_READONLY - LTEXT "Status",IDC_CFG_LBL_STATE,90,38,22,8 - EDITTEXT IDC_CFG_STATE,134,35,109,14,ES_AUTOHSCROLL | ES_READONLY - LTEXT "Depends on",IDC_CFG_LBL_DEPS,90,52,39,8 - LISTBOX IDC_CFG_DEPS,134,52,109,34,LBS_SORT | - LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP - PUSHBUTTON "Enable",IDC_CFG_ENABLE,134,90,50,14 - PUSHBUTTON "Disable",IDC_CFG_DISABLE,193,90,50,14 - GROUPBOX "Provided by",IDC_CFG_PROVGRP,86,111,162,47 - LTEXT "Module",IDC_CFG_LBL_MOD,90,124,24,8 - EDITTEXT IDC_CFG_MODULE,134,121,109,14,ES_AUTOHSCROLL | + LVS_SHOWSELALWAYS | LVS_ALIGNLEFT | WS_BORDER | + WS_TABSTOP,7,7,75,168 + ICON IDI_CFG_PLUGIN,IDC_CFG_ICON,87,11,20,20 + EDITTEXT IDC_CFG_DESC,128,7,120,30,ES_MULTILINE | ES_AUTOVSCROLL | ES_READONLY - LTEXT "Vendor",IDC_CFG_LBL_VEN,90,142,24,8 - EDITTEXT IDC_CFG_VENDOR,133,139,110,14,ES_AUTOHSCROLL | + LTEXT "&Module",IDC_CFG_LBL_MOD,87,43,24,8 + EDITTEXT IDC_CFG_MODULE,128,43,120,12,ES_AUTOHSCROLL | ES_READONLY - PUSHBUTTON "Register new plugin ...",IDC_CFG_REGISTER,163,161,85,14, + LTEXT "&Version",IDC_STATIC,87,59,24,8 + EDITTEXT IDC_CFG_VERSION,128,59,120,12,ES_AUTOHSCROLL | + ES_READONLY + LTEXT "Ve&ndor",IDC_CFG_LBL_VEN,87,75,24,8 + EDITTEXT IDC_CFG_VENDOR,128,75,120,12,ES_AUTOHSCROLL | + ES_READONLY + LTEXT "De&pends on",IDC_CFG_LBL_DEPS,87,93,39,8 + LISTBOX IDC_CFG_DEPS,128,93,120,34,LBS_SORT | + LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP + LTEXT "&Status",IDC_CFG_LBL_STATE,87,129,22,8 + EDITTEXT IDC_CFG_STATE,128,129,120,12,ES_AUTOHSCROLL | + ES_READONLY + PUSHBUTTON "&Enable ...",IDC_CFG_ENABLE,128,144,50,14,WS_DISABLED + PUSHBUTTON "&Disable ...",IDC_CFG_DISABLE,198,144,50,14,WS_DISABLED + PUSHBUTTON "&Unregister plugin ...",IDC_CFG_UNREGISTER,87,161,72,14, WS_DISABLED + PUSHBUTTON "&Register new plugin ...",IDC_CFG_REGISTER,169,161,79, + 14,NOT WS_VISIBLE | WS_DISABLED END IDD_CFG_IDENTITY DIALOGEX 0, 0, 255, 182 @@ -483,10 +502,8 @@ BEGIN BEGIN LEFTMARGIN, 7 RIGHTMARGIN, 248 - VERTGUIDE, 86 - VERTGUIDE, 90 - VERTGUIDE, 134 - VERTGUIDE, 243 + VERTGUIDE, 87 + VERTGUIDE, 128 TOPMARGIN, 7 BOTTOMMARGIN, 175 END @@ -554,7 +571,7 @@ BEGIN IDS_CFG_GENERAL_SHORT "General" IDS_ACTION_NEW_CRED "&New credentials ..." IDS_ACTION_PASSWD_ID "Change &password ..." - IDS_ACTION_CHOOSE_COLS "Choose columns ..." + IDS_ACTION_CHOOSE_COLS "View columns" IDS_ACTION_DEBUG_WINDOW "Debug window ..." IDS_ACTION_VIEW_REFRESH "Refresh" IDS_MENU_LAYOUT "Layout" @@ -693,6 +710,32 @@ BEGIN IDS_NC_ID_DEF " This identity is the default
" IDS_NC_ID_WDEF "Will be the default. (Don't make default)
" IDS_NC_ID_NDEF "Not default identity. (make default)
" + IDS_PACTION_YES "&Yes" + IDS_PACTION_NO "&No" + IDS_PACTION_YESALL "Y&es to all" + IDS_PACTION_NOALL "N&o to all" + IDS_PACTION_KEEP "&Keep" + IDS_PACTION_REMOVE "&Remove" + IDS_PACTION_DISCARD "&Discard" +END + +STRINGTABLE +BEGIN + IDS_CFG_IT_MOD "Changes need to be applied" + IDS_CFG_IT_APP "Changes have been applied" + IDS_CFG_IT_NONE "No changes" + IDS_CFG_NODESC "(Description for plugin %s is not available)" + IDS_CFG_P_DELCNFT "About to disable plugin %s" + IDS_CFG_P_DELCNFM "Are you sure you want to disable plugin %s ?\n\nOnce disabled, the services provided by the plugin will no longer be available. In addition, any other plugins that depend on this plugin will also become non functional.\n\nNetIDMgr will need to be restarted for the plugin to be deactivated." + IDS_CFG_P_DELCNFS "The following plugins depend on this plugin : %s" + IDS_CFG_P_DELNDEP "No other plugins depend on this plugin." + IDS_CFG_P_ENBCNFT "About to enable plugin %s" + IDS_CFG_P_ENBCNFM "The plugin %s will be marked as enabled. The plugin will be come active the next time NetIDMgr is started." + IDS_PISTATE_FAILINIT "Failed to initialize" + IDS_CFG_P_UNRCNFT "Unregistering plugin %s" + IDS_CFG_P_UNRCNFM "Are you sure you want to unregister plugin %s? In addition to this plugin, any other plugins that are provided by the same module will also be unregistered.\n\nThe plugin will no longer be loaded for subsequent sessions of NetIDMgr." + IDS_CFG_P_UNRCNFS "Note that if the plugin was registered by a seprate installer, it should be unregistered by the same installer and not through NetIDMgr.\n\nThe following plugins will be unregistered: %s" + IDS_ACTION_LAYOUT_CUST "Custom" END #endif // English (U.S.) resources diff --git a/src/windows/identity/ui/main.c b/src/windows/identity/ui/main.c index 6f7f9bd47..6987db3ef 100644 --- a/src/windows/identity/ui/main.c +++ b/src/windows/identity/ui/main.c @@ -26,6 +26,7 @@ #include#include +#include #if DEBUG #include @@ -38,6 +39,8 @@ khm_ui_4 khm_commctl_version = 0; khm_startup_options khm_startup; +khm_version app_version = {KH_VERSION_LIST}; + void khm_init_gui(void) { khui_init_actions(); khui_init_rescache(); @@ -45,9 +48,11 @@ void khm_init_gui(void) { khui_init_toolbar(); khm_init_notifier(); khm_init_config(); + khm_init_debug(); } void khm_exit_gui(void) { + khm_exit_debug(); khm_exit_config(); khm_exit_notifier(); khui_exit_toolbar(); @@ -127,6 +132,7 @@ void khm_register_window_classes(void) { ICC_HOTKEY_CLASS | ICC_LISTVIEW_CLASSES | ICC_TAB_CLASSES | + ICC_INTERNET_CLASSES | #if (_WIN32_WINNT >= 0x501) ((IS_COMMCTL6())? ICC_LINK_CLASS | @@ -319,42 +325,61 @@ BOOL khm_check_ps_message(LPMSG pmsg) { return FALSE; } -WPARAM khm_message_loop(void) { +static HACCEL ha_menu; + +WPARAM khm_message_loop_int(khm_boolean * p_exit) { int r; MSG msg; - HACCEL ha_menu; - ha_menu = khui_create_global_accel_table(); - while(r = GetMessage(&msg, NULL, 0,0)) { + while((r = GetMessage(&msg, NULL, 0,0)) && + (p_exit == NULL || *p_exit)) { if(r == -1) break; if(!khm_check_dlg_message(&msg) && - !khm_check_ps_message(&msg) && - !TranslateAccelerator(khm_hwnd_main, ha_menu, &msg)) { + !khm_check_ps_message(&msg) && + !TranslateAccelerator(khm_hwnd_main, ha_menu, &msg)) { TranslateMessage(&msg); DispatchMessage(&msg); } } - DestroyAcceleratorTable(ha_menu); + return msg.wParam; } +WPARAM khm_message_loop(void) { + WPARAM w; + ha_menu = khui_create_global_accel_table(); + w = khm_message_loop_int(NULL); + DestroyAcceleratorTable(ha_menu); + return w; +} + +/* Handles all context closures which have a signalled error state. + If the context is a top level context, then the errors are + displayed. */ void KHMAPI -khm_module_load_ctx_handler(enum kherr_ctx_event evt, - kherr_context * c) { +khm_err_ctx_completion_handler(enum kherr_ctx_event evt, + kherr_context * c) { kherr_event * e; khui_alert * a; + /* we only handle top level contexts here. For others, we allow + the child contexts to fold upward silently. */ + if (c->parent || !kherr_is_error_i(c)) + return; + for(e = kherr_get_first_event(c); e; e = kherr_get_next_event(e)) { + if (e->severity != KHERR_ERROR && e->severity != KHERR_WARNING) + continue; + kherr_evaluate_event(e); - if ((e->severity == KHERR_ERROR || - e->severity == KHERR_WARNING) && - e->short_desc && - e->long_desc) { + /* we only report errors if there is enough information to + present a message. */ + if (e->short_desc && e->long_desc) { khui_alert_create_empty(&a); @@ -369,9 +394,6 @@ khm_module_load_ctx_handler(enum kherr_ctx_event evt, khui_alert_release(a); } } - - kherr_remove_ctx_handler(khm_module_load_ctx_handler, - c->serial); } static wchar_t helpfile[MAX_PATH] = L""; @@ -405,19 +427,7 @@ HWND khm_html_help(HWND hwnd, wchar_t * suffix, } void khm_load_default_modules(void) { - kherr_context * c; - - _begin_task(KHERR_CF_TRANSITIVE); - kmm_load_default_modules(); - - c = kherr_peek_context(); - kherr_add_ctx_handler(khm_module_load_ctx_handler, - KHERR_CTX_END, - c->serial); - kherr_release_context(c); - - _end_task(); } int WINAPI WinMain(HINSTANCE hInstance, @@ -445,6 +455,8 @@ int WINAPI WinMain(HINSTANCE hInstance, khc_load_schema(NULL, schema_uiconfig); + _start_app: + if(!slave) { /* set this so that we don't accidently invoke an API that @@ -466,6 +478,10 @@ int WINAPI WinMain(HINSTANCE hInstance, kmq_set_completion_handler(KMSG_CRED, kmsg_cred_completion); + kherr_add_ctx_handler(khm_err_ctx_completion_handler, + KHERR_CTX_END, + 0); + /* load the standard plugins */ khm_load_default_modules(); @@ -478,6 +494,8 @@ int WINAPI WinMain(HINSTANCE hInstance, if (!khm_startup.no_main_window) khm_show_main_window(); + khm_refresh_config(); + rv = (int) khm_message_loop(); kmq_set_completion_handler(KMSG_CRED, NULL); @@ -497,6 +515,7 @@ int WINAPI WinMain(HINSTANCE hInstance, wchar_t mapname[256]; DWORD tid; void * xfer; + khm_query_app_version query_app_version; CloseHandle(h_appmutex); @@ -513,6 +532,58 @@ int WINAPI WinMain(HINSTANCE hInstance, if (!hwnd) return 2; + /* first check if the remote instance supports a version + query */ + + StringCbPrintf(mapname, sizeof(mapname), + QUERY_APP_VER_MAP_FMT, + (tid = GetCurrentThreadId())); + + hmap = CreateFileMapping(INVALID_HANDLE_VALUE, + NULL, + PAGE_READWRITE, + 0, + 4096, + mapname); + + if (hmap == NULL) + return 3; + + xfer = MapViewOfFile(hmap, FILE_MAP_WRITE, 0, 0, + sizeof(query_app_version)); + + if (xfer) { + ZeroMemory(&query_app_version, sizeof(query_app_version)); + + query_app_version.magic = KHM_QUERY_APP_VER_MAGIC; + query_app_version.code = KHM_ERROR_NOT_IMPLEMENTED; + query_app_version.ver_caller = app_version; + + query_app_version.request_swap = TRUE; + + memcpy(xfer, &query_app_version, sizeof(query_app_version)); + + SendMessage(hwnd, WM_KHUI_QUERY_APP_VERSION, + 0, (LPARAM) tid); + + memcpy(&query_app_version, xfer, sizeof(query_app_version)); + + UnmapViewOfFile(xfer); + xfer = NULL; + } + + CloseHandle(hmap); + hmap = NULL; + + if (query_app_version.code == KHM_ERROR_SUCCESS && + query_app_version.request_swap) { + /* the request for swap was granted. We can now + initialize our instance as the master instance. */ + + slave = FALSE; + goto _start_app; + } + StringCbPrintf(mapname, sizeof(mapname), COMMANDLINE_MAP_FMT, (tid = GetCurrentThreadId())); @@ -546,7 +617,7 @@ int WINAPI WinMain(HINSTANCE hInstance, CloseHandle(hmap); } -#if 0 +#if defined(DEBUG) && ( defined(KH_BUILD_PRIVATE) || defined(KH_BUILD_SPECIAL)) /* writes a report of memory leaks to the specified file. Should only be enabled on development versions. */ PDUMP("memleak.txt"); diff --git a/src/windows/identity/ui/mainmenu.c b/src/windows/identity/ui/mainmenu.c index 10270f2a0..fc3a64b0c 100644 --- a/src/windows/identity/ui/mainmenu.c +++ b/src/windows/identity/ui/mainmenu.c @@ -81,6 +81,8 @@ void add_action_to_menu(HMENU hm, khui_action * act, wchar_t buf[MAX_RES_STRING] = L""; wchar_t accel[MAX_RES_STRING] = L""; + assert(!act || act->cmd); + mii.cbSize = sizeof(mii); mii.fMask = 0; @@ -90,9 +92,13 @@ void add_action_to_menu(HMENU hm, khui_action * act, } else { khui_menu_def * def; - LoadString(khm_hInstance, - act->is_caption, - buf, ARRAYLENGTH(buf)); + if (act->caption) { + StringCbCopy(buf, sizeof(buf), act->caption); + } else { + LoadString(khm_hInstance, + act->is_caption, + buf, ARRAYLENGTH(buf)); + } if(khui_get_cmd_accel_string(act->cmd, accel, ARRAYLENGTH(accel))) { @@ -126,10 +132,12 @@ void add_action_to_menu(HMENU hm, khui_action * act, mii.hbmpItem = HBMMENU_CALLBACK; } - def = khui_find_menu(act->cmd); - if(def) { - mii.fMask |= MIIM_SUBMENU; - mii.hSubMenu = mm_create_menu_from_def(def, FALSE); + if (flags & KHUI_ACTIONREF_SUBMENU) { + def = khui_find_menu(act->cmd); + if(def) { + mii.fMask |= MIIM_SUBMENU; + mii.hSubMenu = mm_create_menu_from_def(def, FALSE); + } } if(flags & KHUI_ACTIONREF_DEFAULT) @@ -153,6 +161,21 @@ static void refresh_menu_item(HMENU hm, khui_action * act, else { khui_menu_def * def; + /* first check if the menu item is there. Otherwise we need + to add it. */ + mii.fMask = MIIM_STATE; + if (!GetMenuItemInfo(hm, act->cmd, FALSE, &mii)) { + /* the 1000 is fairly arbitrary, but there should be much + less menu items on a menu anyway. If there are that + many items, the system would be unusable to the extent + that the order of the items would be the least of our + worries. */ + add_action_to_menu(hm, act, 1000, flags); + return; + } + + mii.fMask = 0; + if(act->state & KHUI_ACTIONSTATE_DISABLED) { mii.fMask |= MIIM_STATE; mii.fState = MFS_DISABLED; @@ -211,8 +234,8 @@ static HMENU mm_create_menu_from_def(khui_menu_def * def, BOOL main) { act = def->items; i = 0; - while((def->n_items == -1 && act->action != KHUI_MENU_END) || - (def->n_items >= 0 && i < (int) def->n_items)) { + while((!(def->state & KHUI_MENUSTATE_ALLOCD) && act->action != KHUI_MENU_END) || + ((def->state & KHUI_MENUSTATE_ALLOCD) && i < (int) def->n_items)) { add_action_to_menu(hm,khui_find_action(act->action),i,act->flags); act++; i++; } @@ -392,12 +415,15 @@ LRESULT khm_menu_handle_select(WPARAM wParam, LPARAM lParam) { id = LOWORD(wParam); act = khui_find_action(id); - if(act == NULL || act->is_tooltip == 0) + if(act == NULL || (act->is_tooltip == 0 && act->tooltip == NULL)) khm_statusbar_set_part(KHUI_SBPART_INFO, NULL, NULL); else { - LoadString(khm_hInstance, - act->is_tooltip, - buf, ARRAYLENGTH(buf)); + if (act->tooltip) + StringCbCopy(buf, sizeof(buf), act->tooltip); + else + LoadString(khm_hInstance, + act->is_tooltip, + buf, ARRAYLENGTH(buf)); khm_statusbar_set_part(KHUI_SBPART_INFO, NULL, buf); } } @@ -607,9 +633,9 @@ void khm_menu_create_main(HWND parent) { khui_main_menu_toolbar = hwtb; SendMessage(hwtb, - TB_BUTTONSTRUCTSIZE, - (WPARAM) sizeof(TBBUTTON), - 0); + TB_BUTTONSTRUCTSIZE, + (WPARAM) sizeof(TBBUTTON), + 0); for(i=0; i magic != KHM_QUERY_APP_VER_MAGIC) + return; + + papp_ver->ver_remote = app_version; + + /* the remote instance has requested swapping in. we check the + version numbers and if the remote instance is newer than us, + then we exit and let the remote instance take over. */ + if (papp_ver->request_swap) { + khm_version ver_caller = papp_ver->ver_caller; + + if (ver_caller.major > app_version.major || + + (ver_caller.major == app_version.major && + ver_caller.minor > app_version.minor) || + + (ver_caller.major == app_version.major && + ver_caller.minor == app_version.minor && + ver_caller.aux > app_version.aux) || + + (ver_caller.major == app_version.major && + ver_caller.minor == app_version.minor && + ver_caller.aux == app_version.aux && + ver_caller.patch > app_version.patch)) { + + papp_ver->request_swap = TRUE; + + if (khm_hwnd_main) + DestroyWindow(khm_hwnd_main); + + } else { + + papp_ver->request_swap = FALSE; + + } + } + + papp_ver->code = KHM_ERROR_SUCCESS; +} + +LRESULT CALLBACK +khm_main_wnd_proc(HWND hwnd, + UINT uMsg, + WPARAM wParam, + LPARAM lParam) { LPNMHDR lpnm; @@ -92,6 +193,7 @@ LRESULT CALLBACK khm_main_wnd_proc( break; case WM_DESTROY: + khm_pre_shutdown(); kmq_unsubscribe_hwnd(KMSG_ACT, hwnd); kmq_unsubscribe_hwnd(KMSG_CRED, hwnd); HtmlHelp(NULL, NULL, HH_CLOSE_ALL, 0); @@ -136,7 +238,7 @@ LRESULT CALLBACK khm_main_wnd_proc( return 0; case KHUI_ACTION_DESTROY_CRED: - khm_cred_destroy_creds(); + khm_cred_destroy_creds(FALSE, FALSE); return 0; case KHUI_ACTION_SET_DEF_ID: @@ -155,12 +257,16 @@ LRESULT CALLBACK khm_main_wnd_proc( khm_hide_main_window(); break; - case KHUI_ACTION_OPT_KHIM: - khm_show_config_pane(NULL); + case KHUI_ACTION_OPT_KHIM: { + khui_config_node node = NULL; + + khui_cfg_open(NULL, L"KhmGeneral", &node); + khm_show_config_pane(node); + } break; case KHUI_ACTION_OPT_IDENTS: { - khui_config_node node; + khui_config_node node = NULL; khui_cfg_open(NULL, L"KhmIdentities", &node); khm_show_config_pane(node); @@ -168,7 +274,7 @@ LRESULT CALLBACK khm_main_wnd_proc( break; case KHUI_ACTION_OPT_NOTIF: { - khui_config_node node; + khui_config_node node = NULL; khui_cfg_open(NULL, L"KhmNotifications", &node); khm_show_config_pane(node); @@ -176,7 +282,7 @@ LRESULT CALLBACK khm_main_wnd_proc( break; case KHUI_ACTION_OPT_PLUGINS: { - khui_config_node node; + khui_config_node node = NULL; khui_cfg_open(NULL, L"KhmPlugins", &node); khm_show_config_pane(node); @@ -216,16 +322,27 @@ LRESULT CALLBACK khm_main_wnd_proc( mm_last_hot_item = LOWORD(lParam); return khm_menu_activate(MENU_ACTIVATE_DEFAULT); + case KHUI_PACTION_ESC: + /* if esc is pressed while no menu is active, we close the + main window */ + if (mm_last_hot_item == -1) { + khm_close_main_window(); + return 0; + } + /* generic, retargetting */ case KHUI_PACTION_UP: case KHUI_PACTION_UP_TOGGLE: case KHUI_PACTION_UP_EXTEND: + case KHUI_PACTION_PGUP: + case KHUI_PACTION_PGUP_EXTEND: case KHUI_PACTION_DOWN: case KHUI_PACTION_DOWN_TOGGLE: case KHUI_PACTION_DOWN_EXTEND: + case KHUI_PACTION_PGDN: + case KHUI_PACTION_PGDN_EXTEND: case KHUI_PACTION_LEFT: case KHUI_PACTION_RIGHT: - case KHUI_PACTION_ESC: case KHUI_PACTION_ENTER: /* menu tracking */ if(mm_last_hot_item != -1) { @@ -251,16 +368,27 @@ LRESULT CALLBACK khm_main_wnd_proc( } /*FALLTHROUGH*/ - case KHUI_PACTION_DELETE: case KHUI_PACTION_SELALL: case KHUI_ACTION_LAYOUT_ID: case KHUI_ACTION_LAYOUT_TYPE: case KHUI_ACTION_LAYOUT_LOC: + case KHUI_ACTION_LAYOUT_CUST: /* otherwise fallthrough and bounce to the creds window */ return SendMessage(khm_hwnd_main_cred, uMsg, wParam, lParam); + + default: + /* handle custom actions here */ + { + khui_action * act; + + act = khui_find_action(LOWORD(wParam)); + if (act && act->listener) { + kmq_post_sub_msg(act->listener, KMSG_ACT, KMSG_ACT_ACTIVATE, act->cmd, NULL); + } + } } break; /* WM_COMMAND */ @@ -271,34 +399,7 @@ LRESULT CALLBACK khm_main_wnd_proc( return 0; case SC_CLOSE: - { - khm_handle csp_cw; - BOOL keep_running = FALSE; - - if (KHM_SUCCEEDED(khc_open_space(NULL, L"CredWindow", - KHM_PERM_READ, &csp_cw))) { - khm_int32 t; - - if (KHM_SUCCEEDED(khc_read_int32(csp_cw, L"KeepRunning", - &t))) - keep_running = t; -#ifdef DEBUG - else - assert(FALSE); -#endif - - khc_close_space(csp_cw); - } -#ifdef DEBUG - else - assert(FALSE); -#endif - - if (keep_running) - khm_hide_main_window(); - else - DestroyWindow(hwnd); - } + khm_close_main_window(); return 0; } break; @@ -416,6 +517,27 @@ LRESULT CALLBACK khm_main_wnd_proc( } else if (m->type == KMSG_ACT && m->subtype == KMSG_ACT_CONTINUE_CMDLINE) { khm_cred_process_commandline(); + } else if (m->type == KMSG_ACT && + m->subtype == KMSG_ACT_SYNC_CFG) { + khm_refresh_config(); + } else if (m->type == KMSG_ACT && + m->subtype == KMSG_ACT_ACTIVATE) { + /* some custom action fired */ + + khm_int32 action; + khui_action * paction; + + action = m->uparam; + paction = khui_find_action(action); + if (paction && paction->data == (void *) CFGACTION_MAGIC) { + /* a custom configuration needs to be invoked */ + khui_config_node node; + + if (KHM_SUCCEEDED(khui_cfg_open(NULL, paction->name, &node))) { + khm_show_config_pane(node); + khui_cfg_release(node); + } + } } else if (m->type == KMSG_CRED && m->subtype == KMSG_CRED_REFRESH) { mw_restart_refresh_timer(hwnd); @@ -466,20 +588,49 @@ LRESULT CALLBACK khm_main_wnd_proc( khm_cred_begin_commandline(); } break; + + case WM_KHUI_QUERY_APP_VERSION: + { + HANDLE hmap; + void * xfer; + wchar_t mapname[256]; + + StringCbPrintf(mapname, sizeof(mapname), + QUERY_APP_VER_MAP_FMT, (DWORD) lParam); + + hmap = OpenFileMapping(FILE_MAP_READ | FILE_MAP_WRITE, + FALSE, mapname); + + if (hmap == NULL) + return 1; + + xfer = MapViewOfFile(hmap, FILE_MAP_WRITE, 0, 0, + sizeof(khm_query_app_version)); + + if (xfer) { + khm_process_query_app_ver((khm_query_app_version *) xfer); + + UnmapViewOfFile(xfer); + } + + CloseHandle(hmap); + } + break; + } return DefWindowProc(hwnd,uMsg,wParam,lParam); } -LRESULT CALLBACK khm_null_wnd_proc( - HWND hwnd, - UINT uMsg, - WPARAM wParam, - LPARAM lParam - ) { +LRESULT CALLBACK +khm_null_wnd_proc(HWND hwnd, + UINT uMsg, + WPARAM wParam, + LPARAM lParam) { return DefWindowProc(hwnd, uMsg, wParam, lParam); } -LRESULT khm_rebar_notify(LPNMHDR lpnm) { +LRESULT +khm_rebar_notify(LPNMHDR lpnm) { switch(lpnm->code) { #if (_WIN32_WINNT >= 0x0501) case RBN_AUTOBREAK: @@ -508,7 +659,8 @@ LRESULT khm_rebar_notify(LPNMHDR lpnm) { return 1; } -void khm_create_main_window_controls(HWND hwnd_main) { +void +khm_create_main_window_controls(HWND hwnd_main) { REBARINFO rbi; HWND hwRebar; @@ -552,7 +704,8 @@ void khm_create_main_window_controls(HWND hwnd_main) { khm_hwnd_main_cred = khm_create_credwnd(hwnd_main); } -void khm_create_main_window(void) { +void +khm_create_main_window(void) { wchar_t buf[1024]; khm_handle csp_cw = NULL; khm_handle csp_mw = NULL; @@ -615,9 +768,11 @@ void khm_create_main_window(void) { NULL, NULL); + khui_set_main_window(khm_hwnd_main); } -void khm_show_main_window(void) { +void +khm_show_main_window(void) { if (khm_nCmdShow == SW_RESTORE) { HWND hw; @@ -639,7 +794,39 @@ void khm_show_main_window(void) { khm_nCmdShow = SW_RESTORE; } -void khm_hide_main_window(void) { +void +khm_close_main_window(void) { + khm_handle csp_cw; + BOOL keep_running = FALSE; + + if (KHM_SUCCEEDED(khc_open_space(NULL, L"CredWindow", + KHM_PERM_READ, &csp_cw))) { + khm_int32 t; + + if (KHM_SUCCEEDED(khc_read_int32(csp_cw, L"KeepRunning", + &t))) { + keep_running = t; + } else { +#ifdef DEBUG + assert(FALSE); +#endif + } + + khc_close_space(csp_cw); + } else { +#ifdef DEBUG + assert(FALSE); +#endif + } + + if (keep_running) + khm_hide_main_window(); + else + DestroyWindow(khm_hwnd_main); +} + +void +khm_hide_main_window(void) { khm_handle csp_notices = NULL; khm_int32 show_warning = FALSE; @@ -674,11 +861,13 @@ void khm_hide_main_window(void) { ShowWindow(khm_hwnd_main, SW_HIDE); } -BOOL khm_is_main_window_visible(void) { +BOOL +khm_is_main_window_visible(void) { return IsWindowVisible(khm_hwnd_main); } -BOOL khm_is_main_window_active(void) { +BOOL +khm_is_main_window_active(void) { if (!IsWindowVisible(khm_hwnd_main)) return FALSE; if (GetForegroundWindow() == khm_hwnd_main) @@ -686,7 +875,8 @@ BOOL khm_is_main_window_active(void) { return khm_is_dialog_active(); } -void khm_register_main_wnd_class(void) { +void +khm_register_main_wnd_class(void) { WNDCLASSEX wc; wc.cbSize = sizeof(WNDCLASSEX); @@ -704,7 +894,6 @@ void khm_register_main_wnd_class(void) { khm_null_window_class = RegisterClassEx(&wc); - wc.cbSize = sizeof(WNDCLASSEX); wc.style = CS_DBLCLKS | CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc = khm_main_wnd_proc; @@ -721,7 +910,8 @@ void khm_register_main_wnd_class(void) { khm_main_window_class = RegisterClassEx(&wc); } -void khm_unregister_main_wnd_class(void) { +void +khm_unregister_main_wnd_class(void) { UnregisterClass(MAKEINTATOM(khm_main_window_class),khm_hInstance); UnregisterClass(MAKEINTATOM(khm_null_window_class),khm_hInstance); } diff --git a/src/windows/identity/ui/mainwnd.h b/src/windows/identity/ui/mainwnd.h index 95b28b733..526248b1d 100644 --- a/src/windows/identity/ui/mainwnd.h +++ b/src/windows/identity/ui/mainwnd.h @@ -39,6 +39,7 @@ void khm_unregister_main_wnd_class(void); void khm_create_main_window_controls(HWND); void khm_create_main_window(void); void khm_show_main_window(void); +void khm_close_main_window(void); void khm_hide_main_window(void); BOOL khm_is_main_window_visible(void); BOOL khm_is_main_window_active(void); @@ -54,7 +55,9 @@ khm_main_wnd_proc(HWND hwnd, LPARAM lParam); #define WM_KHUI_ASSIGN_COMMANDLINE 32808 +#define WM_KHUI_QUERY_APP_VERSION 32809 #define COMMANDLINE_MAP_FMT L"Local\\NetIDMgr_Cmdline_%lu" +#define QUERY_APP_VER_MAP_FMT L"Local\\NetIDMgr_QueryVer_%lu" #endif diff --git a/src/windows/identity/ui/netidmgr.manifest.amd64.vc7 b/src/windows/identity/ui/netidmgr.manifest.amd64.vc7 new file mode 100644 index 000000000..0db331bb7 --- /dev/null +++ b/src/windows/identity/ui/netidmgr.manifest.amd64.vc7 @@ -0,0 +1,22 @@ + + + diff --git a/src/windows/identity/ui/netidmgr.manifest.amd64.vc7.debug b/src/windows/identity/ui/netidmgr.manifest.amd64.vc7.debug new file mode 100644 index 000000000..0db331bb7 --- /dev/null +++ b/src/windows/identity/ui/netidmgr.manifest.amd64.vc7.debug @@ -0,0 +1,22 @@ + ++ Khimaira Credentials Manager ++ ++ ++ + diff --git a/src/windows/identity/ui/netidmgr.manifest.amd64.vc8 b/src/windows/identity/ui/netidmgr.manifest.amd64.vc8 new file mode 100644 index 000000000..6fb1e8d1e --- /dev/null +++ b/src/windows/identity/ui/netidmgr.manifest.amd64.vc8 @@ -0,0 +1,31 @@ + ++ Khimaira Credentials Manager ++ ++ ++ + diff --git a/src/windows/identity/ui/netidmgr.manifest.amd64.vc8.debug b/src/windows/identity/ui/netidmgr.manifest.amd64.vc8.debug new file mode 100644 index 000000000..6fb1e8d1e --- /dev/null +++ b/src/windows/identity/ui/netidmgr.manifest.amd64.vc8.debug @@ -0,0 +1,31 @@ + ++ Khimaira Credentials Manager ++ ++ ++ + ++ + diff --git a/src/windows/identity/ui/newcredwnd.c b/src/windows/identity/ui/newcredwnd.c index 619b79687..3730a3c6e 100644 --- a/src/windows/identity/ui/newcredwnd.c +++ b/src/windows/identity/ui/newcredwnd.c @@ -899,7 +899,7 @@ nc_handle_wm_command(HWND hwnd, switch(LOWORD(wParam)) { case IDOK: - d->nc->result = KHUI_NC_RESULT_GET_CREDS; + d->nc->result = KHUI_NC_RESULT_PROCESS; /* fallthrough */ @@ -1178,7 +1178,7 @@ static LRESULT nc_handle_wm_nc_notify(HWND hwnd, if (d->nc->types[i]->dlg_proc == NULL) { d->nc->types[i]->hwnd_panel = NULL; } else { - /* Create the dialog panel */ + /* Create the dialog panel */ d->nc->types[i]->hwnd_panel = CreateDialogParam(d->nc->types[i]->h_module, d->nc->types[i]->dlg_template, diff --git a/src/windows/identity/ui/notifier.c b/src/windows/identity/ui/notifier.c index b7ac46262..cde643ab2 100644 --- a/src/windows/identity/ui/notifier.c +++ b/src/windows/identity/ui/notifier.c @@ -51,6 +51,8 @@ HWND hwnd_notifier = NULL; BOOL notifier_ready = FALSE; +khm_boolean notifier_modal_loop = FALSE; + khui_alert * current_alert = NULL; khui_alert * alert_queue[KHUI_ALERT_QUEUE_MAX]; @@ -184,6 +186,23 @@ notifier_wnd_proc(HWND hwnd, } } break; + + case KMSG_ALERT_SHOW_MODAL: + { + khui_alert * a; + + a = (khui_alert *) m->vparam; + a->flags |= KHUI_ALERT_FLAG_MODAL; + rv = alert_show(a); + khui_alert_release(a); + + if (KHM_SUCCEEDED(rv)) { + notifier_modal_loop = TRUE; + + khm_message_loop_int(¬ifier_modal_loop); + } + } + break; } } else if (m->type == KMSG_CRED && m->subtype == KMSG_CRED_ROOTDELTA) { @@ -251,6 +270,7 @@ notifier_wnd_proc(HWND hwnd, } } /* fallthrough */ + case NIN_BALLOONHIDE: case NIN_BALLOONTIMEOUT: khm_notify_icon_change(KHERR_NONE); if (current_alert) { @@ -259,6 +279,7 @@ notifier_wnd_proc(HWND hwnd, } break; #endif + } } else if (uMsg == WM_TIMER) { if (wParam == KHUI_TRIGGER_TIMER_ID) { @@ -445,7 +466,16 @@ alert_show_normal(khui_alert * a) { khui_alert_add_command(a, KHUI_PACTION_CLOSE); } - if (!is_alert_queue_empty()) { + /* if there are other alerts queued up, we should add a 'Next + alert...' button that when clicked, would show the next queued + alert. However, we only do this if the current alert doesn't + actually require a command response. Otherwise, clicking the + 'next' button will be the equivalent of cancelling out of the + alert without selecting any of the commands. */ + if (!is_alert_queue_empty() && + a->n_alert_commands == 1 && + a->alert_commands[0] == KHUI_PACTION_CLOSE) { + khui_alert_add_command(a, KHUI_PACTION_NEXT); } @@ -457,14 +487,15 @@ alert_show_normal(khui_alert * a) { CreateWindowEx(WS_EX_DLGMODALFRAME | WS_EX_CONTEXTHELP, MAKEINTATOM(atom_alerter), title, - WS_DLGFRAME | WS_POPUPWINDOW | WS_CLIPCHILDREN | - WS_VISIBLE, + WS_DLGFRAME | WS_POPUPWINDOW | WS_CLIPCHILDREN, 0, 0, 300, 300, // bogus values khm_hwnd_main, (HMENU) NULL, khm_hInstance, (LPVOID) a); + ShowWindow(hwa, SW_SHOW); + return KHM_ERROR_SUCCESS; } @@ -491,8 +522,9 @@ alert_show(khui_alert * a) { /* depending on the state of the main window, we need to either show a window or a balloon */ - if(khm_is_main_window_active() && - !(a->flags & KHUI_ALERT_FLAG_REQUEST_BALLOON)) + if ((a->flags & KHUI_ALERT_FLAG_MODAL) || + (khm_is_main_window_active() && + !(a->flags & KHUI_ALERT_FLAG_REQUEST_BALLOON))) return alert_show_normal(a); else return alert_show_minimized(a); @@ -676,7 +708,9 @@ alerter_wnd_proc(HWND hwnd, CreateWindowEx(0, L"BUTTON", caption, - WS_VISIBLE | WS_CHILD, + WS_VISIBLE | WS_CHILD | + /* the first button is the default */ + ((i==0)? BS_DEFPUSHBUTTON: 0), x,y,width,height, hwnd, (HMENU)(INT_PTR) (action->cmd), @@ -719,6 +753,8 @@ alerter_wnd_proc(HWND hwnd, khui_alert_lock(d->alert); d->alert->flags &= ~KHUI_ALERT_FLAG_DISPLAY_WINDOW; + if (d->alert->flags & KHUI_ALERT_FLAG_MODAL) + notifier_modal_loop = FALSE; khui_alert_unlock(d->alert); khui_alert_release(d->alert); @@ -935,6 +971,8 @@ alerter_wnd_proc(HWND hwnd, SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOZORDER); + InvalidateRect(hwnd, NULL, TRUE); + x = d->x_message; y = d->dy_client - d->dy_bb; width = d->dx_button; diff --git a/src/windows/identity/ui/reqdaemon.c b/src/windows/identity/ui/reqdaemon.c index 04056566d..684f6c74a 100644 --- a/src/windows/identity/ui/reqdaemon.c +++ b/src/windows/identity/ui/reqdaemon.c @@ -137,7 +137,7 @@ reqdaemonwnd_proc(HWND hwnd, sizeof(widname)))) continue; else { - lr = (result != KHUI_NC_RESULT_GET_CREDS); + lr = (result != KHUI_NC_RESULT_PROCESS); break; } } while(TRUE); diff --git a/src/windows/identity/ui/resource.h b/src/windows/identity/ui/resource.h index b8060c6a0..19396fb23 100644 --- a/src/windows/identity/ui/resource.h +++ b/src/windows/identity/ui/resource.h @@ -1,6 +1,6 @@ //{{NO_DEPENDENCIES}} // Microsoft Visual C++ generated include file. -// Used by D:\work\pismere\athena\auth\krb5\src\windows\identity\ui\lang\en_us\khapp.rc +// Used by C:\work\pismere\athena\auth\krb5\src\windows\identity\ui\lang\en_us\khapp.rc // #define IDI_MAIN_APP 104 #define IDD_PROPPAGE_MEDIUM 106 @@ -207,8 +207,11 @@ #define IDI_ICON4 206 #define IDI_APPICON_OK 206 #define IDS_PISTATE_FAILREG 207 +#define IDI_CFG_PLUGIN 207 #define IDS_PISTATE_FAILDIS 208 +#define IDI_CFG_PLUGIN_ERR 208 #define IDS_PISTATE_FAILLOD 209 +#define IDI_CFG_PLUGIN_DIS 209 #define IDS_PISTATE_PLACEHOLD 210 #define IDS_PISTATE_REG 211 #define IDS_PISTATE_HOLD 212 @@ -232,6 +235,28 @@ #define IDS_NC_ID_DEF 230 #define IDS_NC_ID_WDEF 231 #define IDS_NC_ID_NDEF 232 +#define IDS_PACTION_YES 233 +#define IDS_PACTION_NO 234 +#define IDS_PACTION_YESALL 235 +#define IDS_PACTION_NOALL 236 +#define IDS_PACTION_KEEP 237 +#define IDS_PACTION_REMOVE 238 +#define IDS_PACTION_DISCARD 239 +#define IDS_CFG_IT_MOD 240 +#define IDS_CFG_IT_APP 241 +#define IDS_CFG_IT_NONE 242 +#define IDS_CFG_NODESC 243 +#define IDS_CFG_P_DELCNFT 244 +#define IDS_CFG_P_DELCNFM 245 +#define IDS_CFG_P_DELCNFS 246 +#define IDS_CFG_P_DELNDEP 247 +#define IDS_CFG_P_ENBCNFT 248 +#define IDS_CFG_P_ENBCNFM 249 +#define IDS_PISTATE_FAILINIT 250 +#define IDS_CFG_P_UNRCNFT 251 +#define IDS_CFG_P_UNRCNFM 252 +#define IDS_CFG_P_UNRCNFS 253 +#define IDS_ACTION_LAYOUT_CUST 254 #define IDC_NC_USERNAME 1007 #define IDC_NC_PASSWORD 1008 #define IDC_NC_CREDTEXT_LABEL 1009 @@ -312,6 +337,13 @@ #define IDC_LIST1 1103 #define IDC_MODULES 1103 #define IDC_PP_CONFIG 1104 +#define IDC_CFG_UNREGISTER 1107 +#define IDC_CFG_VERSION 1108 +#define IDC_CFG_ICON 1109 +#define IDC_CFG_LOGTOFILE 1110 +#define IDC_CFG_LOGPATH 1111 +#define IDC_NOTIF_HALFLIFE 1112 +#define IDC_CFG_DESTROYALL 1113 #define IDA_ACTIVATE_MENU 40003 #define IDA_UP 40004 #define IDA_DOWN 40005 @@ -324,9 +356,9 @@ // #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 207 +#define _APS_NEXT_RESOURCE_VALUE 210 #define _APS_NEXT_COMMAND_VALUE 40010 -#define _APS_NEXT_CONTROL_VALUE 1107 +#define _APS_NEXT_CONTROL_VALUE 1114 #define _APS_NEXT_SYMED_VALUE 101 #endif #endif diff --git a/src/windows/identity/ui/timer.c b/src/windows/identity/ui/timer.c index 5d28e6a58..40464d5ad 100644 --- a/src/windows/identity/ui/timer.c +++ b/src/windows/identity/ui/timer.c @@ -27,6 +27,12 @@ #include+ Khimaira Credentials Manager ++ ++ ++ + ++ #include +/* The minimum half time interval is 60 seconds*/ +#define TT_MIN_HALFLIFE_INTERVAL 60 + +/* as above, in FILETIME units of 100ns */ +#define FT_MIN_HALFLIFE_INTERVAL (TT_MIN_HALFLIFE_INTERVAL * 10000000i64) + /* in seconds */ #if 0 khm_int32 khui_timeout_warn = KHUI_DEF_TIMEOUT_WARN; @@ -161,11 +167,11 @@ tmr_fire_timer(void) { khui_timers[i].flags |= KHUI_TE_FLAG_EXPIRED; } -#ifdef DEBUG else { +#ifdef DEBUG assert(FALSE); - } #endif + } } } } @@ -323,6 +329,71 @@ tmr_find(khm_handle key, khui_timer_type type, return -1; } +/* called with cs_timers held. */ +static FILETIME +tmr_next_halflife_timeout(int idx, FILETIME * issue, FILETIME * expire) { + FILETIME lifetime; + FILETIME current; + FILETIME ret; + + khm_int64 ilife; + khm_int64 icurrent; + khm_int64 iexpire; + + khm_int64 iret; + + GetSystemTimeAsFileTime(¤t); + + /* wha?? */ + if (CompareFileTime(issue, expire) >= 0) + return current; + + lifetime = FtSub(expire, issue); + icurrent = FtToInt(¤t); + iexpire = FtToInt(expire); + + ilife = FtToInt(&lifetime); + + while(ilife / 2 > FT_MIN_HALFLIFE_INTERVAL) { + ilife /= 2; + + /* is this the next renewal time? */ + if (iexpire - ilife > icurrent) { + if (idx >= 0 && + khui_timers[idx].expire == iexpire - ilife && + (khui_timers[idx].flags & KHUI_TE_FLAG_EXPIRED)) { + + /* if this renewal time has already been triggered + (note that when the timer fires, it also fires all + events that are within a few seconds of the current + time) then we need to set the alarm for the next + slot down the line. */ + + continue; + + } else { + break; + } + } + } + + iret = iexpire - ilife; + + ret = IntToFt(iret); + + /* if the previous renew timer had fired, we need to mark it as + not expired. However, we leave it to the caller to update the + actual timer and mark it as not stale. */ + if (idx >= 0 && + khui_timers[idx].expire < (khm_ui_8) iret) { + + khui_timers[idx].flags &= ~KHUI_TE_FLAG_EXPIRED; + khui_timers[idx].expire = iret; + } + + return ret; +} + /* called with cs_timers held */ static khm_int32 KHMAPI tmr_cred_apply_proc(khm_handle cred, void * rock) { @@ -333,6 +404,8 @@ tmr_cred_apply_proc(khm_handle cred, void * rock) { FILETIME ft_current; FILETIME ft_creinst; FILETIME ft_cred_expiry; + FILETIME ft_cred_issue; + FILETIME ft_issue; FILETIME ft; FILETIME fte; FILETIME ft_reinst; @@ -347,7 +420,8 @@ tmr_cred_apply_proc(khm_handle cred, void * rock) { cb = sizeof(ft_expiry); if (KHM_FAILED(kcdb_identity_get_attr(ident, KCDB_ATTR_EXPIRE, NULL, - &ft_expiry, &cb))) + &ft_expiry, &cb))) { + cb = sizeof(ft_expiry); if (KHM_FAILED(kcdb_cred_get_attr(cred, KCDB_ATTR_EXPIRE, NULL, &ft_expiry, &cb))) { @@ -355,6 +429,22 @@ tmr_cred_apply_proc(khm_handle cred, void * rock) { kcdb_identity_release(ident); return KHM_ERROR_SUCCESS; } + } + + cb = sizeof(ft_issue); + if (KHM_FAILED(kcdb_identity_get_attr(ident, KCDB_ATTR_ISSUE, + NULL, + &ft_issue, &cb))) { + cb = sizeof(ft_issue); + if (KHM_FAILED(kcdb_cred_get_attr(cred, KCDB_ATTR_ISSUE, + NULL, + &ft_issue, &cb))) { + /* we don't really abandon the timer. In this case, we + fall back to using the threshold value to set the + expiry timer. */ + ZeroMemory(&ft_issue, sizeof(ft_issue)); + } + } /* and the current time */ GetSystemTimeAsFileTime(&ft_current); @@ -383,6 +473,7 @@ tmr_cred_apply_proc(khm_handle cred, void * rock) { khm_boolean do_warn = TRUE; khm_boolean do_crit = TRUE; khm_boolean do_renew = TRUE; + khm_boolean do_halflife = TRUE; khm_boolean renew_done = FALSE; khm_boolean monitor = TRUE; khm_int32 to_warn = KHUI_DEF_TIMEOUT_WARN; @@ -423,6 +514,10 @@ tmr_cred_apply_proc(khm_handle cred, void * rock) { if (KHM_SUCCEEDED(rv)) do_renew = t; + rv = khc_read_int32(csp_id, L"RenewAtHalfLife", &t); + if (KHM_SUCCEEDED(rv)) + do_halflife = t; + rv = khc_read_int32(csp_id, L"WarnThreshold", &t); if (KHM_SUCCEEDED(rv)) to_warn = t; @@ -441,16 +536,21 @@ tmr_cred_apply_proc(khm_handle cred, void * rock) { int prev; TimetToFileTimeInterval(to_renew, &ft); - fte = FtSub(&ft_expiry, &ft); prev = tmr_find(ident, KHUI_TTYPE_ID_RENEW, 0, 0); + if (do_halflife) + fte = tmr_next_halflife_timeout(prev, &ft_issue, &ft_expiry); + else + fte = FtSub(&ft_expiry, &ft); + /* we set off a renew notification immediately if the renew threshold has passed but a renew was never sent. This maybe because that NetIDMgr was started at the last minute, or because for some reason the renew timer could not be triggered earlier. */ + if (CompareFileTime(&fte, &ft_current) > 0 || prev == -1 || !(khui_timers[prev].flags & KHUI_TE_FLAG_EXPIRED)) { @@ -462,14 +562,18 @@ tmr_cred_apply_proc(khm_handle cred, void * rock) { FtToInt(&fte), FtToInt(&ft), 0, CompareFileTime(&fte,&ft_creinst) > 0); renew_done = TRUE; + } else { + /* special case. If the renew timer was in the past and it was expired, then we retain the record as long as the credentials are around. If the renewal failed we don't want to automatically retry everytime we check the timers. */ + tmr_update(ident, KHUI_TTYPE_ID_RENEW, FtToInt(&fte), FtToInt(&ft), 0, FALSE); + } } @@ -512,9 +616,21 @@ tmr_cred_apply_proc(khm_handle cred, void * rock) { &cb))) goto _cleanup; + cb = sizeof(ft_cred_issue); + if (KHM_FAILED(kcdb_cred_get_attr(cred, KCDB_ATTR_ISSUE, + NULL, + &ft_cred_issue, + &cb))) + goto _cleanup; + TimetToFileTimeInterval(KHUI_TIMEEQ_ERROR, &ft); { + /* if the credential has a longer lifetime than the identity, + or it expires within KHUI_TIMEEQ_ERROR seconds of the + identity, then we don't need to set any alerts for this + credential. */ + FILETIME ft_delta; ft_delta = FtSub(&ft_expiry, &ft_cred_expiry); @@ -529,12 +645,12 @@ tmr_cred_apply_proc(khm_handle cred, void * rock) { fte = IntToFt(FtToInt(&ft_cred_expiry) - khui_timers[idx].offset); if (CompareFileTime(&fte, &ft_current) > 0) { - tmr_update(cred, KHUI_TTYPE_CRED_WARN, - FtToInt(&fte), - khui_timers[idx].offset, 0, - CompareFileTime(&fte, &ft_creinst) > 0); - kcdb_cred_hold(cred); - } + tmr_update(cred, KHUI_TTYPE_CRED_WARN, + FtToInt(&fte), + khui_timers[idx].offset, 0, + CompareFileTime(&fte, &ft_creinst) > 0); + kcdb_cred_hold(cred); + } } if ((idx = tmr_find(ident, KHUI_TTYPE_ID_CRIT, 0, 0)) >= 0 && @@ -553,7 +669,9 @@ tmr_cred_apply_proc(khm_handle cred, void * rock) { if ((idx = tmr_find(ident, KHUI_TTYPE_ID_RENEW, 0, 0)) >= 0 && !(khui_timers[idx].flags & KHUI_TE_FLAG_STALE)) { - fte = IntToFt(FtToInt(&ft_cred_expiry) - khui_timers[idx].offset); + //fte = IntToFt(FtToInt(&ft_cred_expiry) - khui_timers[idx].offset); + fte = tmr_next_halflife_timeout(idx, &ft_cred_issue, &ft_cred_expiry); + if (CompareFileTime(&fte, &ft_current) > 0) { tmr_update(cred, KHUI_TTYPE_CRED_RENEW, FtToInt(&fte), @@ -648,14 +766,26 @@ khm_timer_refresh(HWND hwnd) { KillTimer(hwnd, KHUI_TRIGGER_TIMER_ID); + /* When refreshing timers, we go through all of them and mark them + as stale. Then we go through the credentials in the root + credential set and add or refresh the timers associated with + each identity and credential. Once this is done, we remove the + timers that are still stale, since they are no longer in + use. */ + for (i=0; i < (int) khui_n_timers; i++) { #ifdef NOT_IMPLEMENTED_YET if (khui_timers[i].type == KHUI_TTYPE_BMSG || khui_timers[i].type == KHUI_TTYPE_SMSG) { khui_timers[i].flags &= ~KHUI_TE_FLAG_STALE; - } else + } else { #endif + khui_timers[i].flags |= KHUI_TE_FLAG_STALE; + +#ifdef NOT_IMPLEMENTED_YET + } +#endif } kcdb_credset_apply(NULL, @@ -666,6 +796,10 @@ khm_timer_refresh(HWND hwnd) { _check_next_event: + /* Before we return, we should check if any timers are set to + expire right now. If there are, we should fire the timer + before returning. */ + next_event = 0; for (i=0; i < (int) khui_n_timers; i++) { if (!(khui_timers[i].flags & KHUI_TE_FLAG_EXPIRED) && diff --git a/src/windows/identity/ui/uiconfig.csv b/src/windows/identity/ui/uiconfig.csv index 14057dded..5c512bbac 100644 --- a/src/windows/identity/ui/uiconfig.csv +++ b/src/windows/identity/ui/uiconfig.csv @@ -6,7 +6,7 @@ CredWindow,KC_SPACE,0,Options for the credentials window AutoDetectNet,KC_INT32,1,Automatically detect network connectivity changes KeepRunning,KC_INT32,1,Keep running after closing Khimaira DefaultView,KC_STRING,ByIdentity, - ViewList,KC_STRING,"ByIdentity,ByLocation", + ViewList,KC_STRING,"ByIdentity,ByLocation,ByType", PaddingHorizontal,KC_INT32,4, PaddingVertical,KC_INT32,2, PaddingHeader,KC_INT32,16, @@ -19,10 +19,13 @@ CredWindow,KC_SPACE,0,Options for the credentials window AllowCritical,KC_INT32,1,Boolean. Enables critical. AutoRenewThreshold,KC_INT32,600,In seconds AllowAutoRenew,KC_INT32,1,Boolean. + RenewAtHalfLife,KC_INT32,1,Boolean. Use half-life algorithm for renewals. DefaultAllowAutoRenew,KC_INT32,1,Default AllowAutoRenew value for new identities DefaultSticky,KC_INT32,0,Default Sticky value for new identities MaxThreshold,KC_INT32,86400,Max value for a threshold (1 day) MinThreshold,KC_INT32,10,Min value for a threshold (0) + LogToFile,KC_INT32,0,Boolean. If true logs trace events to a nidmdbg.log in the temp folder + DestroyCredsOnExit,KC_INT32,0,Boolean. If true; all credentials will be destroyed when NetIDMgr exits. Windows,KC_SPACE,0,Window parameters _Schema,KC_SPACE,0,Schema Width,KC_INT32,0, @@ -35,6 +38,33 @@ CredWindow,KC_SPACE,0,Options for the credentials window Windows,KC_ENDSPACE,0, Views,KC_SPACE,0,Preconfigured views for credentials Custom_0,KC_SPACE,0,First custom view. Additional views have names of the form Custom_N + Description,KC_STRING,Custom view, + ColumnList,KC_STRING,"_CWFlags,IdentityName,TypeName,Name,TimeLeft", + Columns,KC_SPACE,0,Columns + _CWFlags,KC_SPACE,0, + Width,KC_INT32,20, + Flags,KC_INT32,112, + _CWFlags,KC_ENDSPACE,0, + IdentityName,KC_SPACE,0, + Width,KC_INT32,100, + SortIndex,KC_INT32,0, + Flags,KC_INT32,11, + IdentityName,KC_ENDSPACE,0 + TypeName,KC_SPACE,0 + Width,KC_INT32,100 + SortIndex,KC_INT32,1 + Flags,KC_INT32,11 + TypeName,KC_ENDSPACE,0 + Name,KC_SPACE,0 + Width,KC_INT32,200 + SortIndex,KC_INT32,2 + Flags,KC_INT32,3 + Name,KC_ENDSPACE,0 + TimeLeft,KC_SPACE,0 + Width,KC_INT32,200 + Flags,KC_INT32,1 + TimeLeft,KC_ENDSPACE,0 + Columns,KC_ENDSPACE,0 Custom_0,KC_ENDSPACE,0, ByIdentity,KC_SPACE,0,The default view Description,KC_STRING,View grouped by identity and credential type, @@ -42,12 +72,8 @@ CredWindow,KC_SPACE,0,Options for the credentials window Columns,KC_SPACE,0,Columns _CWFlags,KC_SPACE,0, Width,KC_INT32,20, - Flags,KC_INT32,112, + Flags,KC_INT32,112, _CWFlags,KC_ENDSPACE,0, -# _CWTypeIcon,KC_SPACE,0, -# Width,KC_INT32,20, -# Flags,KC_INT32,112, -# _CWTypeIcon,KC_ENDSPACE,0, IdentityName,KC_SPACE,0, Width,KC_INT32,100, SortIndex,KC_INT32,0, @@ -69,18 +95,43 @@ CredWindow,KC_SPACE,0,Options for the credentials window TimeLeft,KC_ENDSPACE,0 Columns,KC_ENDSPACE,0 ByIdentity,KC_ENDSPACE,0 + ByType,KC_SPACE,0,The default view + Description,KC_STRING,View grouped by type and identity, + ColumnList,KC_STRING,"_CWFlags,TypeName,IdentityName,Name,TimeLeft", + Columns,KC_SPACE,0,Columns + _CWFlags,KC_SPACE,0, + Width,KC_INT32,20, + Flags,KC_INT32,112, + _CWFlags,KC_ENDSPACE,0, + TypeName,KC_SPACE,0 + Width,KC_INT32,100 + SortIndex,KC_INT32,0 + Flags,KC_INT32,11 + TypeName,KC_ENDSPACE,0 + IdentityName,KC_SPACE,0, + Width,KC_INT32,100, + SortIndex,KC_INT32,1, + Flags,KC_INT32,11, + IdentityName,KC_ENDSPACE,0 + Name,KC_SPACE,0 + Width,KC_INT32,200 + SortIndex,KC_INT32,2 + Flags,KC_INT32,3 + Name,KC_ENDSPACE,0 + TimeLeft,KC_SPACE,0 + Width,KC_INT32,200 + Flags,KC_INT32,1 + TimeLeft,KC_ENDSPACE,0 + Columns,KC_ENDSPACE,0 + ByType,KC_ENDSPACE,0 ByLocation,KC_SPACE,0,View by location Description,KC_STRING,View grouped by location, ColumnList,KC_STRING,"_CWFlags,Location,IdentityName,TypeName,Name,TimeLeft", Columns,KC_SPACE,0,Columns _CWFlags,KC_SPACE,0, Width,KC_INT32,20, - Flags,KC_INT32,112, + Flags,KC_INT32,112, _CWFlags,KC_ENDSPACE,0, -# _CWTypeIcon,KC_SPACE,0, -# Width,KC_INT32,20, -# Flags,KC_INT32,112, -# _CWTypeIcon,KC_ENDSPACE,0, Location,KC_SPACE,0, Width,KC_INT32,100, SortIndex,KC_INT32,0, diff --git a/src/windows/identity/uilib/accel.csv b/src/windows/identity/uilib/accel.csv index a97b37ba4..f95e89bc8 100644 --- a/src/windows/identity/uilib/accel.csv +++ b/src/windows/identity/uilib/accel.csv @@ -3,9 +3,13 @@ KHUI_PACTION_MENU,FVIRTKEY,VK_F10,KHUI_ACCEL_SCOPE_GLOBAL KHUI_PACTION_UP,FVIRTKEY,VK_UP,KHUI_ACCEL_SCOPE_GLOBAL KHUI_PACTION_UP_EXTEND,FVIRTKEY|FSHIFT,VK_UP,KHUI_ACCEL_SCOPE_GLOBAL KHUI_PACTION_UP_TOGGLE,FVIRTKEY|FCONTROL,VK_UP,KHUI_ACCEL_SCOPE_GLOBAL +KHUI_PACTION_PGUP,FVIRTKEY,VK_PRIOR,KHUI_ACCEL_SCOPE_GLOBAL +KHUI_PACTION_PGUP_EXTEND,FVIRTKEY|FSHIFT,VK_PRIOR,KHUI_ACCEL_SCOPE_GLOBAL KHUI_PACTION_DOWN,FVIRTKEY,VK_DOWN,KHUI_ACCEL_SCOPE_GLOBAL KHUI_PACTION_DOWN_EXTEND,FVIRTKEY|FSHIFT,VK_DOWN,KHUI_ACCEL_SCOPE_GLOBAL KHUI_PACTION_DOWN_TOGGLE,FVIRTKEY|FCONTROL,VK_DOWN,KHUI_ACCEL_SCOPE_GLOBAL +KHUI_PACTION_PGDN,FVIRTKEY,VK_NEXT,KHUI_ACCEL_SCOPE_GLOBAL +KHUI_PACTION_PGDN_EXTEND,FVIRTKEY|FSHIFT,VK_NEXT,KHUI_ACCEL_SCOPE_GLOBAL KHUI_PACTION_LEFT,FVIRTKEY,VK_LEFT,KHUI_ACCEL_SCOPE_GLOBAL KHUI_PACTION_RIGHT,FVIRTKEY,VK_RIGHT,KHUI_ACCEL_SCOPE_GLOBAL KHUI_PACTION_ENTER,FVIRTKEY,VK_RETURN,KHUI_ACCEL_SCOPE_GLOBAL diff --git a/src/windows/identity/uilib/acceldef.cfg b/src/windows/identity/uilib/acceldef.cfg index 5dc72e610..3be4f2e46 100644 --- a/src/windows/identity/uilib/acceldef.cfg +++ b/src/windows/identity/uilib/acceldef.cfg @@ -28,6 +28,7 @@ This file was autogenerated from src/ui/acceldef.cfg and src/ui/accel.csv. Do not modify directly. */ +#define NOEXPORT #include khui_accel_def khui_accel_global[] = { diff --git a/src/windows/identity/uilib/action.c b/src/windows/identity/uilib/action.c index b337eb894..4f68bbfa6 100644 --- a/src/windows/identity/uilib/action.c +++ b/src/windows/identity/uilib/action.c @@ -30,11 +30,11 @@ #include khui_action_ref khui_main_menu[] = { - MENU_ACTION(KHUI_MENU_FILE), - MENU_ACTION(KHUI_MENU_CRED), - MENU_ACTION(KHUI_MENU_VIEW), - MENU_ACTION(KHUI_MENU_OPTIONS), - MENU_ACTION(KHUI_MENU_HELP), + MENU_SUBMENU(KHUI_MENU_FILE), + MENU_SUBMENU(KHUI_MENU_CRED), + MENU_SUBMENU(KHUI_MENU_VIEW), + MENU_SUBMENU(KHUI_MENU_OPTIONS), + MENU_SUBMENU(KHUI_MENU_HELP), MENU_END() }; @@ -53,7 +53,10 @@ khui_action_ref khui_menu_cred[] = { MENU_ACTION(KHUI_ACTION_DESTROY_CRED), MENU_SEP(), MENU_ACTION(KHUI_ACTION_SET_DEF_ID), +#if 0 + /* not implemented yet */ MENU_ACTION(KHUI_ACTION_SET_SRCH_ID), +#endif MENU_SEP(), MENU_ACTION(KHUI_ACTION_PASSWD_ID), MENU_END() @@ -63,6 +66,7 @@ khui_action_ref khui_menu_layout[] = { MENU_ACTION(KHUI_ACTION_LAYOUT_ID), MENU_ACTION(KHUI_ACTION_LAYOUT_TYPE), MENU_ACTION(KHUI_ACTION_LAYOUT_LOC), + MENU_ACTION(KHUI_ACTION_LAYOUT_CUST), MENU_END() }; @@ -72,12 +76,18 @@ khui_action_ref khui_menu_toolbars[] = { }; khui_action_ref khui_menu_view[] = { - MENU_ACTION(KHUI_ACTION_CHOOSE_COLS), - MENU_ACTION(KHUI_MENU_LAYOUT), - MENU_ACTION(KHUI_MENU_TOOLBARS), + MENU_SUBMENU(KHUI_MENU_COLUMNS), + MENU_SUBMENU(KHUI_MENU_LAYOUT), +#if 0 + /* not implemented yet */ + MENU_SUBMENU(KHUI_MENU_TOOLBARS), +#endif MENU_SEP(), +#if 0 + /* not implemented yet */ MENU_ACTION(KHUI_ACTION_DEBUG_WINDOW), MENU_SEP(), +#endif MENU_ACTION(KHUI_ACTION_VIEW_REFRESH), MENU_END() }; @@ -87,6 +97,7 @@ khui_action_ref khui_menu_options[] = { MENU_ACTION(KHUI_ACTION_OPT_IDENTS), MENU_ACTION(KHUI_ACTION_OPT_NOTIF), MENU_ACTION(KHUI_ACTION_OPT_PLUGINS), + MENU_SEP(), MENU_END() }; @@ -157,6 +168,16 @@ khui_action_ref khui_menu_ico_ctx_normal[] = { MENU_END() }; +khui_action_ref khui_menu_cwheader_ctx[] = { + MENU_SUBMENU(KHUI_MENU_COLUMNS), + MENU_SUBMENU(KHUI_MENU_LAYOUT), + MENU_END() +}; + +khui_action_ref khui_menu_columns[] = { + MENU_END() +}; + khui_action_ref khui_pmenu_tok_sel[] = { MENU_ACTION(KHUI_ACTION_RENEW_CRED), MENU_ACTION(KHUI_ACTION_DESTROY_CRED), @@ -171,23 +192,25 @@ khui_action_ref khui_pmenu_id_sel[] = { /* all stock menus and toolbars */ khui_menu_def khui_all_menus[] = { - CONSTMENU(KHUI_MENU_MAIN, KHUI_MENUSTATE_CONSTANT, khui_main_menu), - CONSTMENU(KHUI_MENU_FILE, KHUI_MENUSTATE_CONSTANT, khui_menu_file), - CONSTMENU(KHUI_MENU_CRED, KHUI_MENUSTATE_CONSTANT, khui_menu_cred), - CONSTMENU(KHUI_MENU_VIEW, KHUI_MENUSTATE_CONSTANT, khui_menu_view), - CONSTMENU(KHUI_MENU_LAYOUT, KHUI_MENUSTATE_CONSTANT, khui_menu_layout), - CONSTMENU(KHUI_MENU_TOOLBARS, KHUI_MENUSTATE_CONSTANT, khui_menu_toolbars), - CONSTMENU(KHUI_MENU_OPTIONS, KHUI_MENUSTATE_CONSTANT, khui_menu_options), - CONSTMENU(KHUI_MENU_HELP, KHUI_MENUSTATE_CONSTANT, khui_menu_help), + CONSTMENU(KHUI_MENU_MAIN, KHUI_MENUSTATE_CONSTANT | KHUI_MENUSTATE_SYSTEM, khui_main_menu), + CONSTMENU(KHUI_MENU_FILE, KHUI_MENUSTATE_CONSTANT | KHUI_MENUSTATE_SYSTEM, khui_menu_file), + CONSTMENU(KHUI_MENU_CRED, KHUI_MENUSTATE_CONSTANT | KHUI_MENUSTATE_SYSTEM, khui_menu_cred), + CONSTMENU(KHUI_MENU_VIEW, KHUI_MENUSTATE_CONSTANT | KHUI_MENUSTATE_SYSTEM, khui_menu_view), + CONSTMENU(KHUI_MENU_LAYOUT, KHUI_MENUSTATE_CONSTANT | KHUI_MENUSTATE_SYSTEM, khui_menu_layout), + CONSTMENU(KHUI_MENU_TOOLBARS, KHUI_MENUSTATE_CONSTANT | KHUI_MENUSTATE_SYSTEM, khui_menu_toolbars), + CONSTMENU(KHUI_MENU_OPTIONS, KHUI_MENUSTATE_CONSTANT | KHUI_MENUSTATE_SYSTEM, khui_menu_options), + CONSTMENU(KHUI_MENU_HELP, KHUI_MENUSTATE_CONSTANT | KHUI_MENUSTATE_SYSTEM, khui_menu_help), + CONSTMENU(KHUI_MENU_COLUMNS, KHUI_MENUSTATE_CONSTANT | KHUI_MENUSTATE_SYSTEM, khui_menu_columns), /* toolbars */ - CONSTMENU(KHUI_TOOLBAR_STANDARD, KHUI_MENUSTATE_CONSTANT, khui_toolbar_standard), + CONSTMENU(KHUI_TOOLBAR_STANDARD, KHUI_MENUSTATE_CONSTANT | KHUI_MENUSTATE_SYSTEM, khui_toolbar_standard), /* context menus */ CONSTMENU(KHUI_MENU_IDENT_CTX, KHUI_MENUSTATE_CONSTANT, khui_menu_ident_ctx), CONSTMENU(KHUI_MENU_TOK_CTX, KHUI_MENUSTATE_CONSTANT, khui_menu_tok_ctx), CONSTMENU(KHUI_MENU_ICO_CTX_MIN, KHUI_MENUSTATE_CONSTANT, khui_menu_ico_ctx_min), CONSTMENU(KHUI_MENU_ICO_CTX_NORMAL, KHUI_MENUSTATE_CONSTANT, khui_menu_ico_ctx_normal), + CONSTMENU(KHUI_MENU_CWHEADER_CTX, KHUI_MENUSTATE_CONSTANT, khui_menu_cwheader_ctx), /* pseudo menus */ CONSTMENU(KHUI_PMENU_TOK_SEL, KHUI_MENUSTATE_CONSTANT, khui_pmenu_tok_sel), @@ -195,8 +218,22 @@ khui_menu_def khui_all_menus[] = { }; int khui_n_all_menus = sizeof(khui_all_menus) / sizeof(khui_menu_def); +khui_menu_def ** khui_cust_menus = NULL; +int khui_nc_cust_menus = 0; +int khui_n_cust_menus = 0; CRITICAL_SECTION cs_actions; +#define CACT_NC_ALLOC 32 + +khui_action ** khui_cust_actions = NULL; +int khui_nc_cust_actions = 0; +int khui_n_cust_actions = 0; + +HWND khui_hwnd_main; /* main window, for notifying + action launches and + dispatching messages to the + application. */ + KHMEXP void KHMAPI khui_init_actions(void) { InitializeCriticalSection(&cs_actions); @@ -207,25 +244,208 @@ khui_exit_actions(void) { DeleteCriticalSection(&cs_actions); } +KHMEXP khm_int32 KHMAPI +khui_action_create(const wchar_t * name, + const wchar_t * caption, + const wchar_t * tooltip, + void * userdata, + khm_int32 type, + khm_handle hsub) { + khui_action * act; + khm_int32 action = 0; + int i; + size_t s; + + if (!caption || + FAILED(StringCchLength(caption, KHUI_MAXCCH_SHORT_DESC, &s)) || + (tooltip && FAILED(StringCchLength(tooltip, KHUI_MAXCCH_SHORT_DESC, &s))) || + (type != KHUI_ACTIONTYPE_TRIGGER && type != KHUI_ACTIONTYPE_TOGGLE)) { + return 0; + } + + EnterCriticalSection(&cs_actions); + if (name && (act = khui_find_named_action(name))) { + /* named action already exists */ + action = act->cmd; + goto _done; + } + + for (i=0; i < khui_n_cust_actions; i++) { + if (khui_cust_actions[i] == NULL || + (khui_cust_actions[i]->state & KHUI_ACTIONSTATE_DELETED)) + break; + } + + if (i >= khui_n_cust_actions && + (khui_cust_actions == NULL || + khui_n_cust_actions + 1 > khui_nc_cust_actions)) { + + khui_nc_cust_actions = UBOUNDSS(khui_n_cust_actions + 1, + CACT_NC_ALLOC, + CACT_NC_ALLOC); +#ifdef DEBUG + assert(khui_nc_cust_actions > khui_n_cust_actions + 1); +#endif + khui_cust_actions = PREALLOC(khui_cust_actions, + sizeof(*khui_cust_actions) * khui_nc_cust_actions); +#ifdef DEBUG + assert(khui_cust_actions); +#endif + } + + if (i >= khui_n_cust_actions) { + i = khui_n_cust_actions ++; + act = PMALLOC(sizeof(khui_action)); + } else { + act = khui_cust_actions[i]; + if (act == NULL) + act = PMALLOC(sizeof(khui_action)); + } + +#ifdef DEBUG + assert(act); +#endif + + khui_cust_actions[i] = act; + + ZeroMemory(act, sizeof(*act)); + + act->cmd = KHUI_USERACTION_BASE + i; + act->type = type; + act->name = (name? PWCSDUP(name) : 0); + act->caption = PWCSDUP(caption); + act->tooltip = (tooltip? PWCSDUP(tooltip) : 0); + act->listener = hsub; + act->data = userdata; + act->state = 0; + + action = act->cmd; + + _done: + LeaveCriticalSection(&cs_actions); + + if (action) + kmq_post_message(KMSG_ACT, KMSG_ACT_NEW, action, NULL); + + return action; +} + +KHMEXP void * KHMAPI +khui_action_get_data(khm_int32 action) { + khui_action * act; + + act = khui_find_action(action); + + if (act == NULL) + return NULL; + else + return act->data; +} + +KHMEXP void KHMAPI +khui_action_delete(khm_int32 action) { + khui_action * act; + + act = khui_find_action(action); + + if (act == NULL) + return; + + /* for the moment, even when the action is deleted, we don't free + up the block of memory used by the khui_action structure. When + a new action is created, it will reuse deleted action + structures. */ + EnterCriticalSection(&cs_actions); + act->state |= KHUI_ACTIONSTATE_DELETED; + if (act->name) + PFREE(act->name); + if (act->caption) + PFREE(act->caption); + if (act->tooltip) + PFREE(act->tooltip); + if (act->listener) + kmq_delete_subscription(act->listener); + act->name = NULL; + act->caption = NULL; + act->tooltip = NULL; + act->listener = NULL; + LeaveCriticalSection(&cs_actions); + + kmq_post_message(KMSG_ACT, KMSG_ACT_DELETE, action, NULL); +} + #define MENU_NC_ITEMS 8 KHMEXP khui_menu_def * KHMAPI -khui_menu_create(int cmd) +khui_menu_create(khm_int32 action) { khui_menu_def * d; d = PMALLOC(sizeof(*d)); ZeroMemory(d, sizeof(*d)); - d->cmd = cmd; + d->cmd = action; d->nc_items = MENU_NC_ITEMS; - d->items = PMALLOC(sizeof(*(d->items)) * d->nc_items); + d->items = PMALLOC(sizeof(*(d->items)) * d->nc_items); d->state = KHUI_MENUSTATE_ALLOCD; + if (action) { + int i; + EnterCriticalSection(&cs_actions); + + for (i=0; i < khui_n_cust_menus; i++) { + if (khui_cust_menus[i] == NULL) + break; + } + + if (i >= khui_n_cust_menus) { + + if (khui_n_cust_menus + 1 >= khui_nc_cust_menus) { + khui_nc_cust_menus = UBOUNDSS(khui_n_cust_menus + 1, + CACT_NC_ALLOC, CACT_NC_ALLOC); + khui_cust_menus = + PREALLOC(khui_cust_menus, + sizeof(khui_cust_menus[0]) * khui_nc_cust_menus); + } + + i = khui_n_cust_menus ++; + } + + khui_cust_menus[i] = d; + + LeaveCriticalSection(&cs_actions); + } + return d; } +KHMEXP void KHMAPI +khui_set_main_window(HWND hwnd) { + khui_hwnd_main = hwnd; +} + +KHMEXP void KHMAPI +khui_action_trigger(khm_int32 action, khui_action_context * ctx) { + khui_action_context save; + + if (!khui_hwnd_main) + return; + + if (ctx) { + khui_context_get(&save); + + khui_context_set_indirect(ctx); + } + + SendMessage(khui_hwnd_main, WM_COMMAND, + MAKEWPARAM(action, 0), (LPARAM) 0); + + if (ctx) { + khui_context_set_indirect(&save); + } +} + KHMEXP khui_menu_def * KHMAPI khui_menu_dup(khui_menu_def * src) { @@ -235,16 +455,16 @@ khui_menu_dup(khui_menu_def * src) d = khui_menu_create(src->cmd); - if(src->n_items == -1) + if (!(src->state & KHUI_MENUSTATE_ALLOCD)) n = khui_action_list_length(src->items); else n = src->n_items; - for(i=0; i items[i].flags & KHUI_ACTIONREF_PACTION) { - khui_menu_add_paction(d, src->items[i].p_action, src->items[i].flags); + for (i=0; i items[i].flags & KHUI_ACTIONREF_PACTION) { + khui_menu_insert_paction(d, -1, src->items[i].p_action, src->items[i].flags); } else { - khui_menu_add_action(d, src->items[i].action); + khui_menu_insert_action(d, -1, src->items[i].action, 0); } } @@ -258,8 +478,22 @@ khui_menu_delete(khui_menu_def * d) /* non-allocated menus are assumed to have no pointers to other allocated blocks */ - if(!(d->state & KHUI_MENUSTATE_ALLOCD)) + if(!(d->state & KHUI_MENUSTATE_ALLOCD)) { + /* we shouldn't have tried to delete a constant menu */ +#ifdef DEBUG + assert(FALSE); +#endif return; + } + + EnterCriticalSection(&cs_actions); + for (i=0; i < khui_n_cust_menus; i++) { + if (khui_cust_menus[i] == d) { + khui_cust_menus[i] = NULL; + break; + } + } + LeaveCriticalSection(&cs_actions); for(i=0; i< (int) d->n_items; i++) { if(d->items[i].flags & KHUI_ACTIONREF_FREE_PACTION) @@ -271,8 +505,12 @@ khui_menu_delete(khui_menu_def * d) PFREE(d); } -static void khui_menu_assert_size(khui_menu_def * d, size_t n) +static void +menu_assert_size(khui_menu_def * d, size_t n) { + + assert(d->state & KHUI_MENUSTATE_ALLOCD); + if(n > (int) d->nc_items) { khui_action_ref * ni; @@ -284,34 +522,153 @@ static void khui_menu_assert_size(khui_menu_def * d, size_t n) } } -KHMEXP void KHMAPI khui_menu_add_action(khui_menu_def * d, int id) +static void +menu_const_to_allocd(khui_menu_def * d) { - khui_menu_assert_size(d, d->n_items + 1); - d->items[d->n_items].flags = 0; - d->items[d->n_items ++].action = id; + khui_action_ref * olist; + khui_action_ref * nlist; + khm_size n; + + assert(!(d->state & KHUI_MENUSTATE_ALLOCD)); + + olist = d->items; + n = khui_action_list_length(d->items); + + d->nc_items = UBOUNDSS(n, MENU_NC_ITEMS, MENU_NC_ITEMS); + nlist = PMALLOC(sizeof(d->items[0]) * d->nc_items); + memcpy(nlist, olist, sizeof(d->items[0]) * n); + + d->items = nlist; + d->n_items = n; + d->state |= KHUI_MENUSTATE_ALLOCD; } -KHMEXP void KHMAPI khui_menu_add_paction(khui_menu_def * d, khui_action * act, int flags) +KHMEXP void KHMAPI +khui_menu_insert_action(khui_menu_def * d, khm_size idx, khm_int32 action, khm_int32 flags) { - khui_menu_assert_size(d, d->n_items + 1); - d->items[d->n_items].flags = flags | KHUI_ACTIONREF_PACTION; - d->items[d->n_items ++].p_action = act; + if (!(d->state & KHUI_MENUSTATE_ALLOCD)) + menu_const_to_allocd(d); + + assert(d->state & KHUI_MENUSTATE_ALLOCD); + assert(action == KHUI_MENU_SEP || action > 0); + + if (idx < 0 || idx > d->n_items) + idx = d->n_items; + + menu_assert_size(d, d->n_items + 1); + + if (idx < d->n_items) { + memmove(&d->items[idx + 1], &d->items[idx], (d->n_items - idx) * sizeof(d->items[0])); + } + + d->items[idx].flags = flags; + d->items[idx].action = action; + if (action == KHUI_MENU_SEP) + d->items[idx].flags |= KHUI_ACTIONREF_SEP; + + d->n_items++; +} + +KHMEXP void KHMAPI +khui_menu_insert_paction(khui_menu_def * d, khm_size idx, khui_action * paction, int flags) +{ + + if (paction == NULL) + return; + + if (!(d->state & KHUI_MENUSTATE_ALLOCD)) + menu_const_to_allocd(d); + + assert(d->state & KHUI_MENUSTATE_ALLOCD); + + if (idx < 0 || idx > d->n_items) + idx = d->n_items; + + menu_assert_size(d, d->n_items + 1); + + if (idx < d->n_items) { + memmove(&d->items[idx + 1], &d->items[idx], (d->n_items - idx) * sizeof(d->items[0])); + } + + d->items[idx].flags = flags | KHUI_ACTIONREF_PACTION; + d->items[idx].p_action = paction; + + d->n_items++; } -KHMEXP khui_menu_def * KHMAPI khui_find_menu(int id) { +KHMEXP void KHMAPI +khui_menu_remove_action(khui_menu_def * d, khm_size idx) { + + assert(d->state & KHUI_MENUSTATE_ALLOCD); + + if (idx < 0 || idx >= d->n_items) + return; + + if (idx < d->n_items - 1) { + memmove(&d->items[idx], &d->items[idx + 1], + ((d->n_items - 1) - idx) * sizeof(d->items[0])); + } + + d->n_items--; +} + +KHMEXP khm_size KHMAPI +khui_menu_get_size(khui_menu_def * d) { + + if (d->state & KHUI_MENUSTATE_ALLOCD) + return d->n_items; + else + return khui_action_list_length(d->items); +} + +KHMEXP khui_action_ref * +khui_menu_get_action(khui_menu_def * d, khm_size idx) { + + khm_size n; + + if (d->state & KHUI_MENUSTATE_ALLOCD) + n = d->n_items; + else + n = khui_action_list_length(d->items); + + if (idx < 0 || idx >= n) + return NULL; + + return &d->items[idx]; +} + +KHMEXP khui_menu_def * KHMAPI +khui_find_menu(khm_int32 id) { khui_menu_def * d; int i; - d = khui_all_menus; - for(i=0;i cmd == id) { + d = khui_cust_menus[i]; + break; + } + } + LeaveCriticalSection(&cs_actions); + + return d; + } } -KHMEXP khui_action * KHMAPI khui_find_action(int id) { +KHMEXP khui_action * KHMAPI +khui_find_action(khm_int32 id) { khui_action * act; int i; @@ -321,12 +678,28 @@ KHMEXP khui_action * KHMAPI khui_find_action(int id) { return &act[i]; } - return NULL; + act = NULL; + + EnterCriticalSection(&cs_actions); + if (id >= KHUI_USERACTION_BASE && + (id - KHUI_USERACTION_BASE) < khui_n_cust_actions) { + act = khui_cust_actions[id - KHUI_USERACTION_BASE]; +#ifdef DEBUG + assert(!act || act->cmd == id); +#endif + if (act && act->state & KHUI_ACTIONSTATE_DELETED) + act = NULL; + } + LeaveCriticalSection(&cs_actions); + + return act; } -KHMEXP khui_action * KHMAPI khui_find_named_action(wchar_t * name) { +KHMEXP khui_action * KHMAPI +khui_find_named_action(const wchar_t * name) { int i; khui_action * act; + khui_action ** pact; if(!name) return NULL; @@ -339,25 +712,42 @@ KHMEXP khui_action * KHMAPI khui_find_named_action(wchar_t * name) { return &act[i]; } + pact = khui_cust_actions; + for(i=0;i name) + continue; + + if(!wcscmp(pact[i]->name, name)) { + if (pact[i]->state & KHUI_ACTIONSTATE_DELETED) + return NULL; + else + return pact[i]; + } + } + return NULL; } -KHMEXP size_t KHMAPI khui_action_list_length(khui_action_ref * ref) { +KHMEXP size_t KHMAPI +khui_action_list_length(khui_action_ref * ref) { size_t c = 0; - while(ref && ref->action != KHUI_MENU_END) { + while(ref && ref->action != KHUI_MENU_END && + !(ref->flags & KHUI_ACTIONREF_END)) { c++; ref++; } return c; } -KHMEXP void KHMAPI khui_check_radio_action(khui_menu_def * d, khm_int32 cmd) +KHMEXP void KHMAPI +khui_check_radio_action(khui_menu_def * d, khm_int32 cmd) { khui_action_ref * r; khui_action * act; r = d->items; - while(r && r->action != KHUI_MENU_END) { + while(r && r->action != KHUI_MENU_END && + (!(d->state & KHUI_MENUSTATE_ALLOCD) || (r - d->items) < (int) d->n_items)) { if(r->flags & KHUI_ACTIONREF_PACTION) { act = r->p_action; } else { @@ -376,7 +766,8 @@ KHMEXP void KHMAPI khui_check_radio_action(khui_menu_def * d, khm_int32 cmd) kmq_post_message(KMSG_ACT, KMSG_ACT_CHECK, 0, 0); } -KHMEXP void KHMAPI khui_check_action(int cmd, khm_boolean check) { +KHMEXP void KHMAPI +khui_check_action(khm_int32 cmd, khm_boolean check) { khui_action * act; act = khui_find_action(cmd); @@ -393,14 +784,16 @@ KHMEXP void KHMAPI khui_check_action(int cmd, khm_boolean check) { kmq_post_message(KMSG_ACT, KMSG_ACT_CHECK, 0, 0); } -KHMEXP void KHMAPI khui_enable_actions(khui_menu_def * d, khm_boolean enable) +KHMEXP void KHMAPI +khui_enable_actions(khui_menu_def * d, khm_boolean enable) { khui_action_ref * r; int delta = FALSE; khui_action * act; r = d->items; - while(r && r->action != KHUI_MENU_END) { + while(r && r->action != KHUI_MENU_END && + (!(d->state & KHUI_MENUSTATE_ALLOCD) || (r - d->items) < (int) d->n_items)) { if(r->flags & KHUI_ACTIONREF_PACTION) { act = r->p_action; } else { @@ -426,7 +819,8 @@ KHMEXP void KHMAPI khui_enable_actions(khui_menu_def * d, khm_boolean enable) } } -KHMEXP void KHMAPI khui_enable_action(int cmd, khm_boolean enable) { +KHMEXP void KHMAPI +khui_enable_action(khm_int32 cmd, khm_boolean enable) { khui_action * act; act = khui_find_action(cmd); @@ -443,7 +837,8 @@ KHMEXP void KHMAPI khui_enable_action(int cmd, khm_boolean enable) { kmq_post_message(KMSG_ACT, KMSG_ACT_ENABLE, 0, 0); } -KHMEXP HACCEL KHMAPI khui_create_global_accel_table(void) { +KHMEXP HACCEL KHMAPI +khui_create_global_accel_table(void) { int i; ACCEL * accels; HACCEL ha; @@ -463,9 +858,9 @@ KHMEXP HACCEL KHMAPI khui_create_global_accel_table(void) { } KHMEXP khm_boolean KHMAPI -khui_get_cmd_accel_string(int cmd, +khui_get_cmd_accel_string(khm_int32 cmd, wchar_t * buf, - size_t bufsiz) { + khm_size bufsiz) { int i; khui_accel_def * def; @@ -517,10 +912,46 @@ khui_get_cmd_accel_string(int cmd, ap = L"Enter"; break; + case VK_F1: + ap = L"F1"; + break; + + case VK_F2: + ap = L"F2"; + break; + + case VK_F3: + ap = L"F3"; + break; + + case VK_F4: + ap = L"F4"; + break; + case VK_F5: ap = L"F5"; break; + case VK_F6: + ap = L"F6"; + break; + + case VK_F7: + ap = L"F7"; + break; + + case VK_F8: + ap = L"F8"; + break; + + case VK_F9: + ap = L"F9"; + break; + + case VK_F10: + ap = L"F10"; + break; + case VK_DELETE: ap = L"Del"; break; @@ -824,6 +1255,20 @@ khui_context_set_ex(khui_scope scope, LeaveCriticalSection(&cs_actions); } +KHMEXP void KHMAPI +khui_context_set_indirect(khui_action_context * ctx) +{ + EnterCriticalSection(&cs_actions); + + khuiint_context_release(&khui_ctx); + + khuiint_copy_context(&khui_ctx, ctx); + + khui_context_refresh(); + + LeaveCriticalSection(&cs_actions); +} + KHMEXP void KHMAPI khui_context_refresh(void) { khm_int32 flags; diff --git a/src/windows/identity/uilib/actiondef.cfg b/src/windows/identity/uilib/actiondef.cfg index 14600b0b6..0627a67e5 100644 --- a/src/windows/identity/uilib/actiondef.cfg +++ b/src/windows/identity/uilib/actiondef.cfg @@ -29,6 +29,8 @@ This file was autogenerated from src/ui/actiondef.cfg and src/ui/actions.csv. Do not modify directly. */ +#define NOEXPORT + #include #include #include"../ui/resource.h" @@ -36,11 +38,11 @@ Do not modify directly. khui_action khui_actions [] = { EOS -$record_prefix = "{"; +$record_prefix = "ACTION_FULL("; $record_sep = ",\n"; -$record_postfix = "}"; +$record_postfix = ")"; $file_postfix = < flags & KHUI_ALERT_FLAG_FREE_MESSAGE)) { PFREE(alert->message); - alert->message = NULL; alert->flags &= ~KHUI_ALERT_FLAG_FREE_MESSAGE; - } + alert->message = NULL; + if(message) { alert->message = PMALLOC(cb); StringCbCopy(alert->message, cb, message); @@ -263,6 +263,20 @@ khui_alert_show(khui_alert * alert) return KHM_ERROR_SUCCESS; } +KHMEXP khm_int32 KHMAPI +khui_alert_show_modal(khui_alert * alert) +{ + khm_int32 rv; + + assert(alert->magic == KHUI_ALERT_MAGIC); + + khui_alert_hold(alert); + rv = kmq_send_message(KMSG_ALERT, KMSG_ALERT_SHOW_MODAL, 0, + (void *) alert); + + return rv; +} + KHMEXP khm_int32 KHMAPI khui_alert_queue(khui_alert * alert) { diff --git a/src/windows/identity/uilib/configui.c b/src/windows/identity/uilib/configui.c index 51498c0b2..ae8cd2f7c 100644 --- a/src/windows/identity/uilib/configui.c +++ b/src/windows/identity/uilib/configui.c @@ -182,12 +182,22 @@ khui_cfg_register(khui_config_node vparent, parent = cfgui_node_i_from_handle(vparent); } - //node->owner = kmm_this_plugin(); + /* plugin handles should not be obtained lightly. For the moment, + the cleanup of nodes doesn't happen until module unload and + module unload doesn't happen until all the plugin and module + handles have been freed. */ + /* node->owner = kmm_this_plugin(); */ EnterCriticalSection(&cs_cfgui); TADDCHILD(parent, node); LeaveCriticalSection(&cs_cfgui); + /* when the root config list changes, we need to notify the UI. + this way, the Options menu can be kept in sync. */ + if (parent == cfgui_root_config) { + kmq_post_message(KMSG_ACT, KMSG_ACT_SYNC_CFG, 0, 0); + } + return KHM_ERROR_SUCCESS; } @@ -586,6 +596,11 @@ khui_cfg_set_param(khui_config_node vnode, LPARAM param) { LeaveCriticalSection(&cs_cfgui); } +static void +clear_node_data(khui_config_node_i * node) { + node->n_data = 0; +} + static cfg_node_data * get_node_data(khui_config_node_i * node, void * key, @@ -623,6 +638,10 @@ get_node_data(khui_config_node_i * node, } node->data[node->n_data].key = key; + node->data[node->n_data].hwnd = NULL; + node->data[node->n_data].param = 0; + node->data[node->n_data].flags = 0; + node->n_data++; return &(node->data[node->n_data - 1]); @@ -763,6 +782,8 @@ cfgui_clear_params(khui_config_node_i * node) { node->hwnd = NULL; node->param = 0; node->flags &= KHUI_CNFLAGMASK_STATIC; + clear_node_data(node); + c = TFIRSTCHILD(node); while(c) { cfgui_clear_params(c); @@ -801,8 +822,7 @@ khui_cfg_set_flags(khui_config_node vnode, mask &= KHUI_CNFLAGMASK_DYNAMIC; EnterCriticalSection(&cs_cfgui); - if (cfgui_is_valid_node_handle(vnode) && - hwnd_cfgui != NULL) { + if (cfgui_is_valid_node_handle(vnode)) { node = cfgui_node_i_from_handle(vnode); @@ -926,8 +946,7 @@ khui_cfg_get_flags(khui_config_node vnode) { return 0; EnterCriticalSection(&cs_cfgui); - if (cfgui_is_valid_node_handle(vnode) && - hwnd_cfgui != NULL) { + if (cfgui_is_valid_node_handle(vnode)) { node = cfgui_node_i_from_handle(vnode); @@ -950,8 +969,7 @@ khui_cfg_get_name(khui_config_node vnode, return KHM_ERROR_INVALID_PARAM; EnterCriticalSection(&cs_cfgui); - if (cfgui_is_valid_node_handle(vnode) && - hwnd_cfgui != NULL) { + if (cfgui_is_valid_node_handle(vnode)) { khm_size cb; node = cfgui_node_i_from_handle(vnode); diff --git a/src/windows/identity/uilib/creddlg.c b/src/windows/identity/uilib/creddlg.c index dae98ff68..082f9f257 100644 --- a/src/windows/identity/uilib/creddlg.c +++ b/src/windows/identity/uilib/creddlg.c @@ -247,8 +247,7 @@ khui_cw_del_type(khui_new_creds * c, } KHMEXP khm_int32 KHMAPI -khui_cw_find_type( - khui_new_creds * c, +khui_cw_find_type(khui_new_creds * c, khm_int32 type, khui_new_creds_by_type **t) { @@ -271,8 +270,7 @@ khui_cw_find_type( KHMEXP khm_int32 KHMAPI -khui_cw_enable_type( - khui_new_creds * c, +khui_cw_enable_type(khui_new_creds * c, khm_int32 type, khm_boolean enable) { @@ -299,8 +297,7 @@ khui_cw_enable_type( } KHMEXP khm_boolean KHMAPI -khui_cw_type_succeeded( - khui_new_creds * c, +khui_cw_type_succeeded(khui_new_creds * c, khm_int32 type) { khui_new_creds_by_type * t; @@ -543,8 +540,7 @@ khui_cw_get_prompt_count(khui_new_creds * c, } KHMEXP khm_int32 KHMAPI -khui_cw_get_prompt( - khui_new_creds * c, +khui_cw_get_prompt(khui_new_creds * c, khm_size idx, khui_new_creds_prompt ** prompt) { @@ -570,19 +566,29 @@ KHMEXP khm_int32 KHMAPI khui_cw_sync_prompt_values(khui_new_creds * c) { khm_size i; + khm_size n; + HWND hw; + wchar_t tmpbuf[KHUI_MAXCCH_PROMPT_VALUE]; EnterCriticalSection(&c->cs); - for(i=0;i n_prompts;i++) { + redo_loop: + n = c->n_prompts; + for(i=0; i prompts[i]; if(p->hwnd_edit) { - /* Ideally, we would retrieve the text to a temporary - buffer with the c->cs released, obtain c->cs and copy the - text to p->value. However, I'm not going to bother as the - code paths we are touching here do not need c->cs while - setting p->value does */ - GetWindowText(p->hwnd_edit, p->value, - KHUI_MAXCCH_PROMPT_VALUE); + hw = p->hwnd_edit; + LeaveCriticalSection(&c->cs); + + GetWindowText(hw, tmpbuf, ARRAYLENGTH(tmpbuf)); + + EnterCriticalSection(&c->cs); + if (n != c->n_prompts) + goto redo_loop; + SecureZeroMemory(p->value, KHUI_MAXCB_PROMPT_VALUE); + StringCchCopy(p->value, KHUI_MAXCCH_PROMPT_VALUE, + tmpbuf); } } LeaveCriticalSection(&c->cs); diff --git a/src/windows/identity/uilib/khaction.h b/src/windows/identity/uilib/khaction.h index fccdab549..e8f6cd64a 100644 --- a/src/windows/identity/uilib/khaction.h +++ b/src/windows/identity/uilib/khaction.h @@ -34,28 +34,74 @@ /*! \brief An action */ typedef struct tag_khui_action { - int cmd; /*!< command id */ - int type; /*!< combination of KHUI_ACTIONTYPE_* */ - wchar_t * name; /*!< name for named actions. NULL if not named. */ - - /* normal, hot and disabled are toolbar sized bitmaps */ - int ib_normal; /*!< normal bitmap (index) */ - int ib_hot; /*!< hot bitmap (index) */ - int ib_disabled; /*!< disabled bitmap (index) */ - - int ib_icon; /*!< index of small (16x16) icon (for menu) */ - int ib_icon_dis; /*!< index of disabled (greyed) icon */ - - int is_caption; /*!< index of string resource for caption */ - int is_tooltip; /*!< same for description / tooltip */ - int ih_topic; /*!< help topic */ - int state; /*!< current state. combination of KHUI_ACTIONSTATE_* */ + khm_int32 cmd; /*!< action identifier */ + khm_int32 type; /*!< combination of KHUI_ACTIONTYPE_* */ + wchar_t * name; /*!< name for named actions. NULL if + not named. */ + + /* The following fields are only for use by NetIDMgr */ + khm_int16 ib_normal; /*!< (internal) normal bitmap (index) (toolbar sized icon) */ + khm_int16 ib_hot; /*!< (internal) hot bitmap (index) (toolbar sized icon) */ + khm_int16 ib_disabled; /*!< (internal) disabled bitmap (index) (toolbar sized icon) */ + + khm_int16 ib_icon; /*!< (internal) index of small (16x16) icon (for menu) (small icon) */ + khm_int16 ib_icon_dis; /*!< (internal) index of disabled (greyed) icon (small icon) */ + + khm_int16 is_caption; /*!< (internal) index of string resource for caption */ + khm_int16 is_tooltip; /*!< (internal) same for description / tooltip */ + khm_int16 ih_topic; /*!< (internal) help topic */ + + /* The following fields are specified for custom actions */ + wchar_t * caption; /*!< Caption (localized) (limited by + KHUI_MAXCCH_SHORT_DESC). The + caption is used for representing the + action in menus and toolbars. */ + wchar_t * tooltip; /*!< Tooltip (localized) (limited by + KHUI_MAXCCH_SHORT_DESC). If this is + specified, whenever the user hovers + over the menu item or toolbar button + representing the action, the tooltip + will be displayed either on a + tooltip window or in the status + bar. */ + khm_handle listener; /*!< Listener of this action. Should be + a handle to a message + subscription. When the action is + invoked, a message of type + ::KMSG_ACT and subtype + ::KMSG_ACT_ACTIVATE will be posted + to this subscriber. The \a uparam + parameter of the message will have + the identifier of the action. */ + void * data; /*!< User data for custom action. This + field is not used by the UI library. + It is reserved for plugins to store + data that is specific for this + action. The data that's passed in + in the \a userdata parameter to + khui_action_create() will be stored + here and can be retrieved by calling + khui_action_get_data(). */ + void * reserved1; /*!< Reserved. */ + void * reserved2; /*!< Reserved. */ + void * reserved3; /*!< Reserved. */ + + /* For all actions */ + int state; /*!< current state. combination of + KHUI_ACTIONSTATE_* */ } khui_action; -/*! \brief Unknown action type */ +/*! \brief Unknown action type + + Unknown action type. + */ #define KHUI_ACTIONTYPE_NONE 0 -/*! \brief A trigger type action */ +/*! \brief A trigger type action + + A trigger action usually triggers some event, which is what pretty + much every action does. +*/ #define KHUI_ACTIONTYPE_TRIGGER 1 /*! \brief A toggle type action @@ -65,12 +111,19 @@ typedef struct tag_khui_action { */ #define KHUI_ACTIONTYPE_TOGGLE 2 -/*! \brief The action is enabled */ +/*! \brief The action is enabled + + This is the default if no other state is specified. Just means + not-disabled. +*/ #define KHUI_ACTIONSTATE_ENABLED 0 + /*! \brief The action is diabled */ #define KHUI_ACTIONSTATE_DISABLED 1 + /*! \brief For toggle type actions, the action is checked */ #define KHUI_ACTIONSTATE_CHECKED 2 + /*! \brief The action is hot Typically this means that the user is hovering the pointing device @@ -78,31 +131,97 @@ typedef struct tag_khui_action { */ #define KHUI_ACTIONSTATE_HOT 4 +/*! \brief The action has been marked for deletion + + For custom actions, this means that the custom action was deleted. + The contents of the custom action fields are no longer valid. + */ +#define KHUI_ACTIONSTATE_DELETED 8 + #ifdef NOEXPORT #define ACTION_SIMPLE(c,cap,des,top) \ - {c,KHUI_ACTIONTYPE_TRIGGER,0,0,0,0,0,cap,des,top,0} + {c,KHUI_ACTIONTYPE_TRIGGER,NULL,0,0,0,0,0,cap,des,top,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0} -#define ACTION_FULL(cmd,type,inormal,ihot,idis,isml,ismld,capt,toolt,topic,state) \ - {cmd,type,inormal,ihot,idis,isml,ismld,capt,toolt,topic,state} +#define ACTION_FULL(cmd,type,name,inormal,ihot,idis,isml,ismld,capt,toolt,topic,state) \ + {cmd,type,name,inormal,ihot,idis,isml,ismld,capt,toolt,topic,NULL,NULL,NULL,NULL,NULL,NULL,NULL,state} #define ACTION_SIMPLE_IMAGE(c,inormal, ihot, idis, isml, ismld,cap, des, top) \ - {c,KHUI_ACTIONTYPE_TRIGGER,inormal,ihot,idis,isml,ismld,cap,des,top,0} + {c,KHUI_ACTIONTYPE_TRIGGER,NULL,inormal,ihot,idis,isml,ismld,cap,des,top,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0} #endif -/*! \brief A reference to an action */ +/*! \brief A reference to an action + + If the \a flags member has the KHUI_ACTIONREF_PACTION bit set, + then the action is referenced by the \a p_action member of the + union. Otherwise the identifier for the action is specified by \a + action member. +*/ typedef struct tag_khui_action_ref { - int flags; + int flags; /*!< A combination of KHUI_ACTIONREF_* */ union { - int action; - khui_action * p_action; + khm_int32 action; /*!< The action identifier for the + action that is being referrred to. + Only valid if + ::KHUI_ACTIONREF_PACTION is not set + in \a flags. */ + khui_action * p_action; /*!< A pointer to the ::khui_action + structure that describes the action + that is being referred to. Only + valid if ::KHUI_ACTIONREF_PACTION is + set. */ }; } khui_action_ref; +/*! \brief A submenu + + There should exist a menu associated with the action that is being + referred. When displaying this action in a menu, the contents of + the associated menu will appear as a submenu. + */ #define KHUI_ACTIONREF_SUBMENU 0x01 + +/*! \brief Separator + + This is not an actual action, but represents a separator between + actions. When displaying this action in a menu or a toolbar, a + separating line will be drawn in place of this action. The \a + action and \a p_action members of the structures are unused if + this flag is set. + */ #define KHUI_ACTIONREF_SEP 0x02 + +/*! \brief Action by reference + + The \a p_action member of the structure points to the + ::khui_action structure that describes the action. + */ #define KHUI_ACTIONREF_PACTION 0x04 + +#ifdef NOEXPORT +/*! \brief Action should be freed + + \note This flag is reserved for internal use in the NetIDMgr + application. Do not use. + */ #define KHUI_ACTIONREF_FREE_PACTION 0x08 + +/*! \brief Marks the end of an action sequence + + \note THis flag is reserved for internal use in the NetIDMgr + application. Do not use. + */ #define KHUI_ACTIONREF_END 0x10 +#endif + +/*! \brief The default action + + When this bit is set in an action reference that describes a menu, + the menu item will be the default item and will be rendered + differently from other menu items. Only useful when defining + context menus. In general, it is good practice to place the + default item at the top of a menu, although the UI library does + not enforce this. This is purely meant as a rendering hint. + */ #define KHUI_ACTIONREF_DEFAULT 0x20 #ifdef NOEXPORT @@ -113,35 +232,94 @@ typedef struct tag_khui_action_ref { #define MENU_END() {KHUI_ACTIONREF_END,KHUI_MENU_END} #endif -/*! \brief Menu definition */ +/*! \brief Menu definition + + Use the khui_menu_create(), khui_menu_insert_action(), + khui_menu_insert_paction(), khui_menu_get_size(), + khui_menu_get_action() functions to create and manipulate custom + menus. Do not manipulate this structure directly as doing so may + cause inconsistencies in the UI library. +*/ typedef struct tag_khui_menu_def { - int cmd; /*!< Action associated with menu */ - int state; /*!< combination of KHUI_MENUSTATE_* */ - size_t n_items; /*!< total number of items or -1 if not - set. If this is -1, then the list of - actions must be terminated with a - ACTION_LIST_END entry. */ - size_t nc_items; /*!< max number of items in the buffer + khm_int32 cmd; /*!< Action associated with menu */ + khm_int32 state; /*!< combination of KHUI_MENUSTATE_* */ + khm_size n_items; /*!< The number of actions in the \a items + list. If this is a custom menu, the + ::KHUI_MENUSTATE_ALLOCD bit will be set, + and the contents of this field will be + valid. Otherwise, the contents of this + field is ignored and the list of actions + must be terminated with a + ACTION_LIST_END action. */ + khm_size nc_items; /*!< max number of items in the buffer alocated for items. Ignored if - KHUI_MENUSTATE_CONSTANT is set in \a - state.*/ + ::KHUI_MENUSTATE_ALLOCD is not set in \a + state. */ khui_action_ref *items; /*!< Action list terminated by, ACTION_LIST_END. If \a n_items is set to a value other than -1, the list doesn't necessarily have to end with a - ACTION_LIST_END. */ + ACTION_LIST_END. When constructing a + menu using khui_menu_* functions, they + will set the size of this list in the \a + n_items member, and there will be no + ACTION_LIST_END action to terminate the + list. */ } khui_menu_def; #ifdef NOEXPORT #define CONSTMENU(c,s,i) {c,s,-1,-1,i} #endif +/*! \brief Unspecified menu + + Used when there is no single command associated with the entire + menu, such as for ad-hoc context menus. + */ +#define KHUI_MENU_NONE -3 + +/*! \brief Menu end indicator + + For static or constant menus this indicates that this action marks + the end of the list of actions which defined the menu. This is + invalid if used in a dynamic menu (a menu with the + ::KHUI_MENUSTATE_ALLOCD bit set). + */ #define KHUI_MENU_END -2 + +/*! \brief Menu separator + + A separator for actions. When displaying a menu or showing a + toolbar based on a menu definition, a separator is rendered as a + bar separating the user interface elements for the actions on + either side of this. +*/ #define KHUI_MENU_SEP -1 +/*! \brief Constant menu + + The contents of the menu cannot be modified (individual actions in + the menu may be modified, but the order and the contents of the + menu itself cannot be modified. + + This is the default if ::KHUI_MENUSTATE_ALLOCD is not specified. + */ #define KHUI_MENUSTATE_CONSTANT 0 + +/*! \brief Variable menu + + The menu is dnamically allocated. The list of actions contained + in the menu can be modified. +*/ #define KHUI_MENUSTATE_ALLOCD 1 +#ifdef NOEXPORT +/* predefined system menu */ +#define KHUI_MENUSTATE_SYSTEM 2 +#endif + +#ifdef NOEXPORT + /*! \brief Accelerator definition */ typedef struct tag_khui_accel_def { int cmd; @@ -152,8 +330,6 @@ typedef struct tag_khui_accel_def { #define KHUI_ACCEL_SCOPE_GLOBAL 0 -#ifdef NOEXPORT - extern khui_accel_def khui_accel_global[]; extern int khui_n_accel_global; @@ -167,11 +343,154 @@ extern int khui_n_all_menus; /* functions */ -KHMEXP khui_menu_def * KHMAPI khui_menu_create(int cmd); -KHMEXP khui_menu_def * KHMAPI khui_menu_dup(khui_menu_def * src); -KHMEXP void KHMAPI khui_menu_delete(khui_menu_def * d); -KHMEXP void KHMAPI khui_menu_add_action(khui_menu_def * d, int id); -KHMEXP void KHMAPI khui_menu_add_paction(khui_menu_def * d, khui_action * act, int flags); +/*! \brief Create a new menu + + Creates a new menu. The returned data structure must be freed by + a call to khui_menu_delete(). Custom menus that are created this + way are not reference counted or maintained by the UI library. + The caller is responsible for calling khui_menu_delete() when the + data is no longer needed. + + Specifiying an action in the \a action parameter will associate + the menu with the specified action. In this case, if the action + is added to another menu with the ::KHUI_ACTIONREF_SUBMENU flag, + this menu will appear as a submenu within that menu. Only one + menu can be associated with any given action. Custom menus can + not be associated with standard actions. + */ +KHMEXP khui_menu_def * KHMAPI +khui_menu_create(khm_int32 action); + +/*! \brief Duplicate a menu + + Creates a copy of the specified menu. The returned data structure + must be freed by a call to khui_menu_delete(). Custom menus are + not reference counted or maintained by the UI library. The caller + is responsible for calling khui_menu_delete() when the data is no + longer needed. + + Note that even if the original menu was associated with an action, + the duplicate will not be. Modifying the duplicate will not + modify the original menu. Only one menu can be associated with an + action. + */ +KHMEXP khui_menu_def * KHMAPI +khui_menu_dup(khui_menu_def * src); + +/*! \brief Delete a menu + + Deletes a menu created by a call to khui_menu_create() or + khui_menu_dup(). This frees up the memory and associated + resources used by the menu definition. The pointer that is passed + in will no longer be valid. + */ +KHMEXP void KHMAPI +khui_menu_delete(khui_menu_def * d); + +/*! \brief Insert an action into a menu + + The action specified by \a cmd will be inserted in to the menu \a + d at index \a idx. + + \param[in] d The menu to insert the action into + + \param[in] idx The index at which to insert the action. The index + is zero based. If \a idx is (-1) or larger than the largest + index in the menu, the item is appended to the menu. + + \param[in] cmd The command representing the action to insert into + the menu. This should be either a standard action, a user + action created with khui_action_create(), or certain pseudo + actions. Not all pseudo actions can be placed on a menu. + + \param[in] flags Flags for the action. This is a combination of + KHUI_ACTIONREF_* constants. Currently, the only constants + that are valid for this function are: ::KHUI_ACTIONREF_SEP, + ::KHUI_ACTIONREF_SUBMENU, ::KHUI_ACTIONREF_DEFAULT. + ::KHUI_ACTIONREF_SEP will be automatically added if the + command is ::KHUI_MENU_SEP. + + \note The ::khui_menu_def structure is not thread safe. Multiple + threads modifying the same ::khui_menu_def structure may cause + thread safety issues. + */ +KHMEXP void KHMAPI +khui_menu_insert_action(khui_menu_def * d, khm_size idx, khm_int32 cmd, khm_int32 flags); + +#define khui_menu_add_action(d,c) khui_menu_insert_action((d),-1,(c),0) +#pragma deprecated(khui_menu_add_action) + +#ifdef NOEXPORT + +/*! \brief Insert an action by reference into a menu + + The action specified by \a act will be inserted into the menu \a d + at index \a idx. + + \param[in] d The menu to inser the action into. + + \param[in] idx The index at which to insert the action. The index + is zero based. If the index is (-1) or is larger than the + largest index in the menu, then the action is appended to the + menu. + + \param[in] act The action to insert. This is added by reference. + It is the callers reponsibility to ensure that the structure + pointed to by \a act is available throughout the lifetime of + the menu. + + \param[in] flags Flags for the action. This is a combination of + KHUI_ACTIONREF_* constants. Currently, the only constants + that are valid for this function are: ::KHUI_ACTIONREF_SEP, + ::KHUI_ACTIONREF_SUBMENU, ::KHUI_ACTIONREF_DEFAULT. For this + function, ::KHUI_ACTIONREF_PACTION will automatically be aded + when adding the action. ::KHUI_ACTIONREF_SEP will be + automatically added if the command is ::KHUI_MENU_SEP. + + \note The ::khui_menu_def structure is not thread safe. Multiple + threads modifying the same ::khui_menu_def structure may cause + thread safety issues. +*/ +KHMEXP void KHMAPI +khui_menu_insert_paction(khui_menu_def * d, khm_size idx, khui_action * act, khm_int32 flags); + +#define khui_menu_add_paction(d,a,f) khui_menu_insert_paction((d),-1,(a),(f)) +#pragma deprecated(khui_menu_add_paction) + +#endif + +/*! \brief Remove an action from a menu + + The action at the specified index will be removed from the menu. + */ +KHMEXP void KHMAPI +khui_menu_remove_action(khui_menu_def * d, khm_size idx); + +/*! \brief Get the number of items in the menu + + Note that the count includes menu separators. The indices of the + menu items range from 0 to one less than the value returned by + this function. + */ +KHMEXP khm_size KHMAPI +khui_menu_get_size(khui_menu_def * d); + +/*! \brief Get the menu item at a specified index + + The returned reference is only valid while the ::khui_menu_def + structure is valid. In addition, the reference becomes invalid if + the list of actions in the menu data structure is modified in any + way. + + If the specified index is out of bounds, then the function returns + NULL. + + \note The ::khui_menu_def structure is not thread safe. Multiple + threads modifying the same ::khui_menu_def structure may cause + thread safety issues. + */ +KHMEXP khui_action_ref * +khui_menu_get_action(khui_menu_def * d, khm_size idx); /*! \brief Action scope identifiers @@ -399,6 +718,16 @@ khui_context_set_ex(khui_scope scope, void * vparam, khm_size cb_vparam); +/*! \brief Set the current UI context using an existing context + + Copies the context specified in \a ctx into the active UI context. + + \param[in] ctx A pointer to a ::khui_action_context structure that + specifies the new UI context. Cannot be NULL. +*/ +KHMEXP void KHMAPI +khui_context_set_indirect(khui_action_context * ctx); + /*! \brief Obtain the current UI context The parameter specified by \a ctx will receive the current UI @@ -501,21 +830,125 @@ khui_context_cursor_filter(khm_handle cred, \return TRUE if the operation was successful. FALSE otherwise. */ -KHMEXP khm_boolean KHMAPI khui_get_cmd_accel_string(int cmd, wchar_t * buf, size_t bufsiz); +KHMEXP khm_boolean KHMAPI khui_get_cmd_accel_string(khm_int32 cmd, wchar_t * buf, khm_size bufsiz); +#ifdef NOEXPORT +/*! \brief Initializes the global accelerator table + */ KHMEXP HACCEL KHMAPI khui_create_global_accel_table(void); +#endif -/*! \brief Find a menu by id */ -KHMEXP khui_menu_def * KHMAPI khui_find_menu(int id); +/*! \brief Find a menu by id -/*! \brief Find an action by id */ -KHMEXP khui_action * KHMAPI khui_find_action(int id); + Finds the menu that is associated with the specified action. + */ +KHMEXP khui_menu_def * KHMAPI khui_find_menu(khm_int32 action); +#ifdef NOEXPORT + +/* internal */ +KHMEXP void KHMAPI +khui_set_main_window(HWND hwnd); + +#endif + +/*! \brief Trigger an action + + Triggers the specified action using the specified UI context. + + This function does not return until the specified action has been + processed. Many standard actions are asynchronous and they will + return before processing will complete. + + Pseudo actions should not be triggered using khui_action_trigger() + as they only carry meaning when invoked from specific windows or + contexts. + + \param[in] action Action. Should be one of the standard actions + or an action created by khui_action_create() + + \param[in] ctx The UI context to use for the action. If this is + NULL, the action will be triggered under the current UI context. + */ +KHMEXP void KHMAPI +khui_action_trigger(khm_int32 action, khui_action_context * ctx); + +/*! \brief Find an action by id + + \note This function should not be used by plugins. It is there + for use by the NetIDMgr application. +*/ +KHMEXP khui_action * KHMAPI khui_find_action(khm_int32 action); + +#ifdef NOEXPORT /*! \brief Get the length of the action list */ KHMEXP size_t KHMAPI khui_action_list_length(khui_action_ref * ref); +#endif + +/*! \brief Create a new action + + \param[in] name Name for a named action. The name must be unique + among all registered actions. (limited by KHUI_MAXCCH_NAME) + (Optional. Set to NULL if the action is not a named action.) + + \param[in] caption The localized caption for the action. This + will be shown in menus, toolbars and buttons when the action + needs to be represented. (limited by KHUI_MAXCCH_SHORT_DESC) + (Required) + + \param[in] tooltip The localized tooltip for the action. (limited + by KHUI_MAXCCH_SHORT_DESC) (Optional, set to NULL if there is + no tooltip associated with the action) + + \param[in] hsub The subscription that is notified when the action + is triggered. (Optional) The subscription can be created with + kmq_create_subscription(). The handle will be released when + it is no longer needed. Hence, the caller should not release + it. + + \param[in] type The type of the action. Currently it should be + set to either ::KHUI_ACTIONTYPE_TRIGGER or + ::KHUI_ACTIONTYPE_TOGGLE. For ::KHUI_ACTIONTYPE_TOGGLE, the + initial state will be unchecked. Use khui_check_action() + function to change the checked state of the action. + + \param[in] userdata A custom value. + + \return The identifier of the new action or zero if the action + could not be created. + + \note For named custom actions, the name of the action can not be + the same as the name of a configuration node. See + khui_cfg_register_node(). + */ +KHMEXP khm_int32 KHMAPI +khui_action_create(const wchar_t * name, + const wchar_t * caption, + const wchar_t * tooltip, + void * userdata, + khm_int32 type, + khm_handle hsub); + +/* \brief Delete a custom action + + Deletes a custom action created by a call to khui_action_create(). + Custom actions should only be deleted when unloading a plugin. + */ +KHMEXP void KHMAPI +khui_action_delete(khm_int32 action); + +/*! \brief Get the user data associated with a custom action + + This function returns the user data that was specified when the + custom action was created usng khui_action_create(). If the + custom action identifier is invalid or if the custom action does + not contain any user data, this function will return NULL. + */ +KHMEXP void * KHMAPI +khui_action_get_data(khm_int32 action); /*! \brief Find an action by name */ -KHMEXP khui_action * KHMAPI khui_find_named_action(wchar_t * name); +KHMEXP khui_action * KHMAPI khui_find_named_action(const wchar_t * name); /*! \brief Enables or disables a group of actions @@ -527,24 +960,32 @@ KHMEXP void KHMAPI khui_enable_actions(khui_menu_def * d, khm_boolean enable); /*! \brief Enables or disables an action - The action designated by the command \a cmd will either be enabled + The action designated by the command \a action will either be enabled or disabled depending on the \a enable parameter. If \a enable is TRUE then the action is enabled. */ -KHMEXP void KHMAPI khui_enable_action(int cmd, khm_boolean enable); +KHMEXP void KHMAPI khui_enable_action(khm_int32 action, khm_boolean enable); /*! \brief Check an action in an action group - Marks the action denoted by \a cmd as checked and resets the + Marks the action denoted by \a action as checked and resets the checked bit in all other actions. \param[in] d A menu definition. - \param[in] cmd A command identifier. Setting this to -1 will + + \param[in] action A command identifier. Setting this to -1 will reset the checked bit in all the actions in the menu definition. */ -KHMEXP void KHMAPI khui_check_radio_action(khui_menu_def * d, khm_int32 cmd); +KHMEXP void KHMAPI khui_check_radio_action(khui_menu_def * d, khm_int32 action); + +/*! \brief Check an action + For toggle typed actions, this sets or resets the check. + */ +KHMEXP void KHMAPI khui_check_action(khm_int32 cmd, khm_boolean check); + +#ifdef NOEXPORT /*!\cond INTERNAL */ /*! \brief Initialize actions @@ -560,6 +1001,7 @@ KHMEXP void KHMAPI khui_init_actions(void); KHMEXP void KHMAPI khui_exit_actions(void); /*! \endcond */ +#endif /*@}*/ /*@}*/ diff --git a/src/windows/identity/uilib/khactiondef.h b/src/windows/identity/uilib/khactiondef.h index 3f1c43073..a5d4799e8 100644 --- a/src/windows/identity/uilib/khactiondef.h +++ b/src/windows/identity/uilib/khactiondef.h @@ -42,7 +42,6 @@ #define KHUI_ACTION_SET_SRCH_ID (KHUI_ACTION_BASE + 4) #define KHUI_ACTION_PASSWD_ID (KHUI_ACTION_BASE + 7) #define KHUI_ACTION_NEW_CRED (KHUI_ACTION_BASE + 8) -#define KHUI_ACTION_CHOOSE_COLS (KHUI_ACTION_BASE + 9) #define KHUI_ACTION_DEBUG_WINDOW (KHUI_ACTION_BASE + 10) #define KHUI_ACTION_VIEW_REFRESH (KHUI_ACTION_BASE + 11) #define KHUI_ACTION_LAYOUT_ID (KHUI_ACTION_BASE + 12) @@ -63,6 +62,7 @@ #define KHUI_ACTION_CLOSE_APP (KHUI_ACTION_BASE + 27) #define KHUI_ACTION_IMPORT (KHUI_ACTION_BASE + 28) #define KHUI_ACTION_OPT_PLUGINS (KHUI_ACTION_BASE + 29) +#define KHUI_ACTION_LAYOUT_CUST (KHUI_ACTION_BASE + 30) /*@}*/ /*! \name Pseudo actions @@ -92,6 +92,17 @@ context. #define KHUI_PACTION_BLANK (KHUI_PACTION_BASE + 15) #define KHUI_PACTION_NEXT (KHUI_PACTION_BASE + 16) #define KHUI_PACTION_SELALL (KHUI_PACTION_BASE + 17) +#define KHUI_PACTION_YES (KHUI_PACTION_BASE + 18) +#define KHUI_PACTION_NO (KHUI_PACTION_BASE + 19) +#define KHUI_PACTION_YESALL (KHUI_PACTION_BASE + 20) +#define KHUI_PACTION_NOALL (KHUI_PACTION_BASE + 21) +#define KHUI_PACTION_REMOVE (KHUI_PACTION_BASE + 22) +#define KHUI_PACTION_KEEP (KHUI_PACTION_BASE + 23) +#define KHUI_PACTION_DISCARD (KHUI_PACTION_BASE + 24) +#define KHUI_PACTION_PGDN (KHUI_PACTION_BASE + 25) +#define KHUI_PACTION_PGUP (KHUI_PACTION_BASE + 26) +#define KHUI_PACTION_PGUP_EXTEND (KHUI_PACTION_BASE + 27) +#define KHUI_PACTION_PGDN_EXTEND (KHUI_PACTION_BASE + 28) /*@}*/ /*! \name Menus @@ -115,6 +126,9 @@ Stock menus. #define KHUI_MENU_TOK_CTX (KHUI_MENU_BASE + 9) #define KHUI_MENU_ICO_CTX_MIN (KHUI_MENU_BASE + 12) #define KHUI_MENU_ICO_CTX_NORMAL (KHUI_MENU_BASE + 13) +#define KHUI_MENU_CWHEADER_CTX (KHUI_MENU_BASE + 14) + +#define KHUI_MENU_COLUMNS (KHUI_MENU_BASE + 15) #define KHUI_PMENU_TOK_SEL (KHUI_MENU_BASE + 10) #define KHUI_PMENU_ID_SEL (KHUI_MENU_BASE + 11) @@ -129,8 +143,15 @@ Stock menus. #define KHUI_TOOLBAR_STANDARD (KHUI_TOOLBAR_BASE + 0) /*@}*/ -/* base for user actions */ +/*! \brief Base for user actions + + When creating new actions, the UI library will allocate command + identifiers starting with this one. +*/ #define KHUI_USERACTION_BASE (KHUI_ACTION_BASE + 10000) + +/*! \brief Does this command represent a user action? */ +#define IS_USERACTION(cmd) ((cmd) >= KHUI_USERACTION_BASE) /*@}*/ /*@}*/ diff --git a/src/windows/identity/uilib/khalerts.h b/src/windows/identity/uilib/khalerts.h index 36b13a333..f10ffa198 100644 --- a/src/windows/identity/uilib/khalerts.h +++ b/src/windows/identity/uilib/khalerts.h @@ -179,6 +179,9 @@ enum khui_alert_flags { KHUI_ALERT_FLAG_REQUEST_BALLOON =0x08000000, /*!< The alert should be displayed in a balloon */ + KHUI_ALERT_FLAG_MODAL =0x10000000, + /*!< Modal alert. Do not set direclty. */ + KHUI_ALERT_FLAGMASK_RDWR =0x0C000010, /*!< Bit mask of flags that can be set by khui_alert_set_flags() */ }; @@ -306,6 +309,19 @@ khui_alert_add_command(khui_alert * alert, KHMEXP khm_int32 KHMAPI khui_alert_show(khui_alert * alert); +/*! \brief Display a modal alert + + Similar to khui_alert_show(), but shows a modal alert dialog. The + function does not return until the user has closed the alert. + + This function always opens an alert window (never shows a + balloon). + + \note Should only be called from the UI thread. + */ +KHMEXP khm_int32 KHMAPI +khui_alert_show_modal(khui_alert * alert); + /*! \brief Queue an alert Instead of displaying the alert immediately, the alert is queued diff --git a/src/windows/identity/uilib/khconfigui.h b/src/windows/identity/uilib/khconfigui.h index ac9fc614c..f124b513f 100644 --- a/src/windows/identity/uilib/khconfigui.h +++ b/src/windows/identity/uilib/khconfigui.h @@ -131,11 +131,17 @@ typedef struct tag_khui_config_node_reg { /*! \brief Node represents a panel that is replicated for all child nodes */ #define KHUI_CNFLAG_PLURAL 0x0004 -#define KHUI_CNFLAG_MODIFIED 0x0010 -#define KHUI_CNFLAG_APPLIED 0x0020 +/*! \brief System node -#define KHUI_CNFLAGMASK_STATIC 0x000f -#define KHUI_CNFLAGMASK_DYNAMIC 0x00f0 + \note For internal use by the NetIDMgr application. Do not use. +*/ +#define KHUI_CNFLAG_SYSTEM 0x0010 + +#define KHUI_CNFLAG_MODIFIED 0x0100 +#define KHUI_CNFLAG_APPLIED 0x0200 + +#define KHUI_CNFLAGMASK_STATIC 0x00ff +#define KHUI_CNFLAGMASK_DYNAMIC 0x0f00 /*! \brief Maximum length of the name in characters @@ -250,6 +256,10 @@ typedef struct tag_khui_config_init_data { of reg were invalid \retval KHM_ERROR_DUPLICATE A node with the same name exists as a child of the specified parent node. + + \note The name (not the short or long description) of the node can + not be the same as the name of a custom action. See + khui_action_create(). */ KHMEXP khm_int32 KHMAPI khui_cfg_register(khui_config_node parent, diff --git a/src/windows/identity/uilib/khnewcred.h b/src/windows/identity/uilib/khnewcred.h index 257434454..45df19779 100644 --- a/src/windows/identity/uilib/khnewcred.h +++ b/src/windows/identity/uilib/khnewcred.h @@ -263,7 +263,7 @@ typedef struct tag_khui_new_creds { khm_size nc_types; /*!< Internal use */ khm_int32 result; /*!< One of ::KHUI_NC_RESULT_CANCEL or - ::KHUI_NC_RESULT_GET_CREDS indicating + ::KHUI_NC_RESULT_PROCESS indicating the result of the dialog with the user */ @@ -296,7 +296,7 @@ typedef struct tag_khui_new_creds { /*!\name Result values for khui_new_creds_t::result @{*/ -#define KHUI_NC_RESULT_GET_CREDS 0 +#define KHUI_NC_RESULT_PROCESS 0 #define KHUI_NC_RESULT_CANCEL 1 /*@}*/ diff --git a/src/windows/identity/uilib/khversion.h b/src/windows/identity/uilib/khversion.h new file mode 100644 index 000000000..d5dc36d24 --- /dev/null +++ b/src/windows/identity/uilib/khversion.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2005 Massachusetts Institute of Technology + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/* $Id$ */ + +#ifndef __KHIMAIRA_KHUIDEFS_H +#define __KHIMAIRA_KHUIDEFS_H + + + +#endif diff --git a/src/windows/identity/uilib/trackerwnd.c b/src/windows/identity/uilib/trackerwnd.c index 814e28808..b0da7d15d 100644 --- a/src/windows/identity/uilib/trackerwnd.c +++ b/src/windows/identity/uilib/trackerwnd.c @@ -307,16 +307,19 @@ duration_edit_proc(HWND hwnd, p = GetParent(hwnd); - /* we are being activated. show the panel */ + /* we are being activated. */ if(tc->hw_slider == NULL) { create_edit_sliders(hwnd, p, tc); initialize_tracker(p, tc); } + khui_tracker_reposition(tc); + +#ifdef SHOW_PANEL_ON_FIRST_ACTIVATE ShowWindow(tc->hw_slider, SW_SHOWNOACTIVATE); +#endif tc->act_time = GetTickCount(); - //SetActiveWindow(p); } break; @@ -338,18 +341,17 @@ duration_edit_proc(HWND hwnd, break; case KHUI_WM_NC_NOTIFY: - if(HIWORD(wParam) == WMNC_DIALOG_SETUP) - { - HWND p; - - p = GetParent(hwnd); + if(HIWORD(wParam) == WMNC_DIALOG_SETUP) { + HWND p; - if(tc->hw_slider == NULL) { - create_edit_sliders(hwnd,p,tc); - } + p = GetParent(hwnd); - initialize_tracker(p, tc); + if(tc->hw_slider == NULL) { + create_edit_sliders(hwnd,p,tc); } + + initialize_tracker(p, tc); + } return TRUE; case WM_LBUTTONUP: @@ -357,7 +359,7 @@ duration_edit_proc(HWND hwnd, DWORD tm; tm = GetTickCount(); - if (tm - tc->act_time > 500) + if (tm - tc->act_time > 000) ShowWindow(tc->hw_slider, SW_HIDE); } else { ShowWindow(tc->hw_slider, SW_SHOWNOACTIVATE); diff --git a/src/windows/identity/util/perfstat.c b/src/windows/identity/util/perfstat.c index 814920dce..6cf8ae44a 100644 --- a/src/windows/identity/util/perfstat.c +++ b/src/windows/identity/util/perfstat.c @@ -41,6 +41,9 @@ typedef struct tag_allocation { int line; size_t size; void * ptr; +#ifdef _WIN32 + DWORD thread; +#endif LDCL(struct tag_allocation); } allocation; @@ -165,6 +168,9 @@ perf_malloc(char * file, int line, size_t s) { a->line = line; a->size = s; a->ptr = ptr; +#ifdef _WIN32 + a->thread = GetCurrentThreadId(); +#endif h = HASHPTR(ptr); @@ -246,11 +252,12 @@ perf_dump(char * file) { return; fprintf(f, "Leaked allocations list ....\n"); - fprintf(f, "File\tLine\tSize\n"); + fprintf(f, "File\tLine\tThread\tSize\n"); for (i=0; i < HASHSIZE; i++) { for (a = ht[i]; a; a = LNEXT(a)) { - fprintf(f, "%s\t%6d\t%6d\n", a->file, a->line, a->size); + fprintf(f, "%s\t%6d\t%6d\t%6d\n", a->file, a->line, + a->thread, a->size); total += a->size; } } -- 2.26.2