SmbFile.cs 147 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836
  1. // This code is derived from jcifs smb client library <jcifs at samba dot org>
  2. // Ported by J. Arturo <webmaster at komodosoft dot net>
  3. //
  4. // This library is free software; you can redistribute it and/or
  5. // modify it under the terms of the GNU Lesser General Public
  6. // License as published by the Free Software Foundation; either
  7. // version 2.1 of the License, or (at your option) any later version.
  8. //
  9. // This library is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. // Lesser General Public License for more details.
  13. //
  14. // You should have received a copy of the GNU Lesser General Public
  15. // License along with this library; if not, write to the Free Software
  16. // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  17. using System;
  18. using System.Collections.Generic;
  19. using System.IO;
  20. using System.Net;
  21. using System.Text;
  22. using SharpCifs.Dcerpc;
  23. using SharpCifs.Dcerpc.Msrpc;
  24. using SharpCifs.Netbios;
  25. using SharpCifs.Util;
  26. using SharpCifs.Util.Sharpen;
  27. using System.Threading.Tasks;
  28. namespace SharpCifs.Smb
  29. {
  30. /// <summary>This class represents a resource on an SMB network.</summary>
  31. /// <remarks>
  32. /// This class represents a resource on an SMB network. Mainly these
  33. /// resources are files and directories however an <code>SmbFile</code>
  34. /// may also refer to servers and workgroups. If the resource is a file or
  35. /// directory the methods of <code>SmbFile</code> follow the behavior of
  36. /// the well known
  37. /// <see cref="FilePath">Sharpen.FilePath</see>
  38. /// class. One fundamental difference
  39. /// is the usage of a URL scheme [1] to specify the target file or
  40. /// directory. SmbFile URLs have the following syntax:
  41. /// <blockquote><pre>
  42. /// smb://[[[domain;]username[:password]@]server[:port]/[[share/[dir/]file]]][?[param=value[param2=value2[...]]]
  43. /// </pre></blockquote>
  44. /// This example:
  45. /// <blockquote><pre>
  46. /// smb://storage15/public/foo.txt
  47. /// </pre></blockquote>
  48. /// would reference the file <code>foo.txt</code> in the share
  49. /// <code>public</code> on the server <code>storage15</code>. In addition
  50. /// to referencing files and directories, jCIFS can also address servers,
  51. /// and workgroups.
  52. /// <p>
  53. /// <font color="#800000"><i>Important: all SMB URLs that represent
  54. /// workgroups, servers, shares, or directories require a trailing slash '/'.
  55. /// </i></font>
  56. /// <p>
  57. /// When using the <tt>java.net.URL</tt> class with
  58. /// 'smb://' URLs it is necessary to first call the static
  59. /// <tt>jcifs.Config.registerSmbURLHandler();</tt> method. This is required
  60. /// to register the SMB protocol handler.
  61. /// <p>
  62. /// The userinfo component of the SMB URL (<tt>domain;user:pass</tt>) must
  63. /// be URL encoded if it contains reserved characters. According to RFC 2396
  64. /// these characters are non US-ASCII characters and most meta characters
  65. /// however jCIFS will work correctly with anything but '@' which is used
  66. /// to delimit the userinfo component from the server and '%' which is the
  67. /// URL escape character itself.
  68. /// <p>
  69. /// The server
  70. /// component may a traditional NetBIOS name, a DNS name, or IP
  71. /// address. These name resolution mechanisms and their resolution order
  72. /// can be changed (See <a href="../../../resolver.html">Setting Name
  73. /// Resolution Properties</a>). The servername and path components are
  74. /// not case sensitive but the domain, username, and password components
  75. /// are. It is also likely that properties must be specified for jcifs
  76. /// to function (See <a href="../../overview-summary.html#scp">Setting
  77. /// JCIFS Properties</a>). Here are some examples of SMB URLs with brief
  78. /// descriptions of what they do:
  79. /// <p>[1] This URL scheme is based largely on the <i>SMB
  80. /// Filesharing URL Scheme</i> IETF draft.
  81. /// <p><table border="1" cellpadding="3" cellspacing="0" width="100%">
  82. /// <tr bgcolor="#ccccff">
  83. /// <td colspan="2"><b>SMB URL Examples</b></td>
  84. /// <tr><td width="20%"><b>URL</b></td><td><b>Description</b></td></tr>
  85. /// <tr><td width="20%"><code>smb://users-nyc;miallen:mypass@angus/tmp/</code></td><td>
  86. /// This URL references a share called <code>tmp</code> on the server
  87. /// <code>angus</code> as user <code>miallen</code> who's password is
  88. /// <code>mypass</code>.
  89. /// </td></tr>
  90. /// <tr><td width="20%">
  91. /// <code>smb://Administrator:P%40ss@msmith1/c/WINDOWS/Desktop/foo.txt</code></td><td>
  92. /// A relativly sophisticated example that references a file
  93. /// <code>msmith1</code>'s desktop as user <code>Administrator</code>. Notice the '@' is URL encoded with the '%40' hexcode escape.
  94. /// </td></tr>
  95. /// <tr><td width="20%"><code>smb://angus/</code></td><td>
  96. /// This references only a server. The behavior of some methods is different
  97. /// in this context(e.g. you cannot <code>delete</code> a server) however
  98. /// as you might expect the <code>list</code> method will list the available
  99. /// shares on this server.
  100. /// </td></tr>
  101. /// <tr><td width="20%"><code>smb://myworkgroup/</code></td><td>
  102. /// This syntactically is identical to the above example. However if
  103. /// <code>myworkgroup</code> happends to be a workgroup(which is indeed
  104. /// suggested by the name) the <code>list</code> method will return
  105. /// a list of servers that have registered themselves as members of
  106. /// <code>myworkgroup</code>.
  107. /// </td></tr>
  108. /// <tr><td width="20%"><code>smb://</code></td><td>
  109. /// Just as <code>smb://server/</code> lists shares and
  110. /// <code>smb://workgroup/</code> lists servers, the <code>smb://</code>
  111. /// URL lists all available workgroups on a netbios LAN. Again,
  112. /// in this context many methods are not valid and return default
  113. /// values(e.g. <code>isHidden</code> will always return false).
  114. /// </td></tr>
  115. /// <tr><td width="20%"><code>smb://angus.foo.net/d/jcifs/pipes.doc</code></td><td>
  116. /// The server name may also be a DNS name as it is in this example. See
  117. /// <a href="../../../resolver.html">Setting Name Resolution Properties</a>
  118. /// for details.
  119. /// </td></tr>
  120. /// <tr><td width="20%"><code>smb://192.168.1.15/ADMIN$/</code></td><td>
  121. /// The server name may also be an IP address. See &lt;a
  122. /// href="../../../resolver.html"&gt;Setting Name Resolution Properties</a>
  123. /// for details.
  124. /// </td></tr>
  125. /// <tr><td width="20%">
  126. /// <code>smb://domain;username:password@server/share/path/to/file.txt</code></td><td>
  127. /// A prototypical example that uses all the fields.
  128. /// </td></tr>
  129. /// <tr><td width="20%"><code>smb://myworkgroup/angus/ &lt;-- ILLEGAL </code></td><td>
  130. /// Despite the hierarchial relationship between workgroups, servers, and
  131. /// filesystems this example is not valid.
  132. /// </td></tr>
  133. /// <tr><td width="20%">
  134. /// <code>smb://server/share/path/to/dir &lt;-- ILLEGAL </code></td><td>
  135. /// URLs that represent workgroups, servers, shares, or directories require a trailing slash '/'.
  136. /// </td></tr>
  137. /// <tr><td width="20%">
  138. /// <code>smb://MYGROUP/?SERVER=192.168.10.15</code></td><td>
  139. /// SMB URLs support some query string parameters. In this example
  140. /// the <code>SERVER</code> parameter is used to override the
  141. /// server name service lookup to contact the server 192.168.10.15
  142. /// (presumably known to be a master
  143. /// browser) for the server list in workgroup <code>MYGROUP</code>.
  144. /// </td></tr>
  145. /// </table>
  146. /// <p>A second constructor argument may be specified to augment the URL
  147. /// for better programmatic control when processing many files under
  148. /// a common base. This is slightly different from the corresponding
  149. /// <code>java.io.File</code> usage; a '/' at the beginning of the second
  150. /// parameter will still use the server component of the first parameter. The
  151. /// examples below illustrate the resulting URLs when this second contructor
  152. /// argument is used.
  153. /// <p><table border="1" cellpadding="3" cellspacing="0" width="100%">
  154. /// <tr bgcolor="#ccccff">
  155. /// <td colspan="3">
  156. /// <b>Examples Of SMB URLs When Augmented With A Second Constructor Parameter</b></td>
  157. /// <tr><td width="20%">
  158. /// <b>First Parameter</b></td><td><b>Second Parameter</b></td><td><b>Result</b></td></tr>
  159. /// <tr><td width="20%"><code>
  160. /// smb://host/share/a/b/
  161. /// </code></td><td width="20%"><code>
  162. /// c/d/
  163. /// </code></td><td><code>
  164. /// smb://host/share/a/b/c/d/
  165. /// </code></td></tr>
  166. /// <tr><td width="20%"><code>
  167. /// smb://host/share/foo/bar/
  168. /// </code></td><td width="20%"><code>
  169. /// /share2/zig/zag
  170. /// </code></td><td><code>
  171. /// smb://host/share2/zig/zag
  172. /// </code></td></tr>
  173. /// <tr><td width="20%"><code>
  174. /// smb://host/share/foo/bar/
  175. /// </code></td><td width="20%"><code>
  176. /// ../zip/
  177. /// </code></td><td><code>
  178. /// smb://host/share/foo/zip/
  179. /// </code></td></tr>
  180. /// <tr><td width="20%"><code>
  181. /// smb://host/share/zig/zag
  182. /// </code></td><td width="20%"><code>
  183. /// smb://foo/bar/
  184. /// </code></td><td><code>
  185. /// smb://foo/bar/
  186. /// </code></td></tr>
  187. /// <tr><td width="20%"><code>
  188. /// smb://host/share/foo/
  189. /// </code></td><td width="20%"><code>
  190. /// ../.././.././../foo/
  191. /// </code></td><td><code>
  192. /// smb://host/foo/
  193. /// </code></td></tr>
  194. /// <tr><td width="20%"><code>
  195. /// smb://host/share/zig/zag
  196. /// </code></td><td width="20%"><code>
  197. /// /
  198. /// </code></td><td><code>
  199. /// smb://host/
  200. /// </code></td></tr>
  201. /// <tr><td width="20%"><code>
  202. /// smb://server/
  203. /// </code></td><td width="20%"><code>
  204. /// ../
  205. /// </code></td><td><code>
  206. /// smb://server/
  207. /// </code></td></tr>
  208. /// <tr><td width="20%"><code>
  209. /// smb://
  210. /// </code></td><td width="20%"><code>
  211. /// myworkgroup/
  212. /// </code></td><td><code>
  213. /// smb://myworkgroup/
  214. /// </code></td></tr>
  215. /// <tr><td width="20%"><code>
  216. /// smb://myworkgroup/
  217. /// </code></td><td width="20%"><code>
  218. /// angus/
  219. /// </code></td><td><code>
  220. /// smb://myworkgroup/angus/ &lt;-- ILLEGAL<br />(But if you first create an <tt>SmbFile</tt> with 'smb://workgroup/' and use and use it as the first parameter to a constructor that accepts it with a second <tt>String</tt> parameter jCIFS will factor out the 'workgroup'.)
  221. /// </code></td></tr>
  222. /// </table>
  223. /// <p>Instances of the <code>SmbFile</code> class are immutable; that is,
  224. /// once created, the abstract pathname represented by an SmbFile object
  225. /// will never change.
  226. /// </remarks>
  227. /// <seealso cref="FilePath">Sharpen.FilePath</seealso>
  228. public class SmbFile : UrlConnection
  229. {
  230. public static void Initialize()
  231. {
  232. SmbTransport.ClearCachedConnections();
  233. SmbConstants.ApplyConfig();
  234. }
  235. internal const int ORdonly = 0x01;
  236. internal const int OWronly = 0x02;
  237. internal const int ORdwr = 0x03;
  238. internal const int OAppend = 0x04;
  239. internal const int OCreat = 0x0010;
  240. internal const int OExcl = 0x0020;
  241. internal const int OTrunc = 0x0040;
  242. /// <summary>
  243. /// When specified as the <tt>shareAccess</tt> constructor parameter,
  244. /// other SMB clients (including other threads making calls into jCIFS)
  245. /// will not be permitted to access the target file and will receive "The
  246. /// file is being accessed by another process" message.
  247. /// </summary>
  248. /// <remarks>
  249. /// When specified as the <tt>shareAccess</tt> constructor parameter,
  250. /// other SMB clients (including other threads making calls into jCIFS)
  251. /// will not be permitted to access the target file and will receive "The
  252. /// file is being accessed by another process" message.
  253. /// </remarks>
  254. public const int FileNoShare = 0x00;
  255. /// <summary>
  256. /// When specified as the <tt>shareAccess</tt> constructor parameter,
  257. /// other SMB clients will be permitted to read from the target file while
  258. /// this file is open.
  259. /// </summary>
  260. /// <remarks>
  261. /// When specified as the <tt>shareAccess</tt> constructor parameter,
  262. /// other SMB clients will be permitted to read from the target file while
  263. /// this file is open. This constant may be logically OR'd with other share
  264. /// access flags.
  265. /// </remarks>
  266. public const int FileShareRead = 0x01;
  267. /// <summary>
  268. /// When specified as the <tt>shareAccess</tt> constructor parameter,
  269. /// other SMB clients will be permitted to write to the target file while
  270. /// this file is open.
  271. /// </summary>
  272. /// <remarks>
  273. /// When specified as the <tt>shareAccess</tt> constructor parameter,
  274. /// other SMB clients will be permitted to write to the target file while
  275. /// this file is open. This constant may be logically OR'd with other share
  276. /// access flags.
  277. /// </remarks>
  278. public const int FileShareWrite = 0x02;
  279. /// <summary>
  280. /// When specified as the <tt>shareAccess</tt> constructor parameter,
  281. /// other SMB clients will be permitted to delete the target file while
  282. /// this file is open.
  283. /// </summary>
  284. /// <remarks>
  285. /// When specified as the <tt>shareAccess</tt> constructor parameter,
  286. /// other SMB clients will be permitted to delete the target file while
  287. /// this file is open. This constant may be logically OR'd with other share
  288. /// access flags.
  289. /// </remarks>
  290. public const int FileShareDelete = 0x04;
  291. /// <summary>
  292. /// A file with this bit on as returned by <tt>getAttributes()</tt> or set
  293. /// with <tt>setAttributes()</tt> will be read-only
  294. /// </summary>
  295. public const int AttrReadonly = 0x01;
  296. /// <summary>
  297. /// A file with this bit on as returned by <tt>getAttributes()</tt> or set
  298. /// with <tt>setAttributes()</tt> will be hidden
  299. /// </summary>
  300. public const int AttrHidden = 0x02;
  301. /// <summary>
  302. /// A file with this bit on as returned by <tt>getAttributes()</tt> or set
  303. /// with <tt>setAttributes()</tt> will be a system file
  304. /// </summary>
  305. public const int AttrSystem = 0x04;
  306. /// <summary>
  307. /// A file with this bit on as returned by <tt>getAttributes()</tt> is
  308. /// a volume
  309. /// </summary>
  310. public const int AttrVolume = 0x08;
  311. /// <summary>
  312. /// A file with this bit on as returned by <tt>getAttributes()</tt> is
  313. /// a directory
  314. /// </summary>
  315. public const int AttrDirectory = 0x10;
  316. /// <summary>
  317. /// A file with this bit on as returned by <tt>getAttributes()</tt> or set
  318. /// with <tt>setAttributes()</tt> is an archived file
  319. /// </summary>
  320. public const int AttrArchive = 0x20;
  321. internal const int AttrCompressed = 0x800;
  322. internal const int AttrNormal = 0x080;
  323. internal const int AttrTemporary = 0x100;
  324. internal const int AttrGetMask = 0x7FFF;
  325. internal const int AttrSetMask = 0x30A7;
  326. internal const int DefaultAttrExpirationPeriod = 5000;
  327. internal static readonly int HashDot = ".".GetHashCode();
  328. internal static readonly int HashDotDot = "..".GetHashCode();
  329. //internal static LogStream log = LogStream.GetInstance();
  330. public LogStream Log
  331. {
  332. get { return LogStream.GetInstance(); }
  333. }
  334. internal static long AttrExpirationPeriod;
  335. internal static bool IgnoreCopyToException;
  336. static SmbFile()
  337. {
  338. // Open Function Encoding
  339. // create if the file does not exist
  340. // fail if the file exists
  341. // truncate if the file exists
  342. // share access
  343. // file attribute encoding
  344. // extended file attribute encoding(others same as above)
  345. /*try
  346. {
  347. Sharpen.Runtime.GetType("jcifs.Config");
  348. }
  349. catch (TypeLoadException cnfe)
  350. {
  351. Sharpen.Runtime.PrintStackTrace(cnfe);
  352. }*/
  353. AttrExpirationPeriod
  354. = Config.GetLong("jcifs.smb.client.attrExpirationPeriod", DefaultAttrExpirationPeriod);
  355. IgnoreCopyToException
  356. = Config.GetBoolean("jcifs.smb.client.ignoreCopyToException", true);
  357. Dfs = new Dfs();
  358. }
  359. /// <summary>
  360. /// Returned by
  361. /// <see cref="GetType()">GetType()</see>
  362. /// if the resource this <tt>SmbFile</tt>
  363. /// represents is a regular file or directory.
  364. /// </summary>
  365. public const int TypeFilesystem = 0x01;
  366. /// <summary>
  367. /// Returned by
  368. /// <see cref="GetType()">GetType()</see>
  369. /// if the resource this <tt>SmbFile</tt>
  370. /// represents is a workgroup.
  371. /// </summary>
  372. public const int TypeWorkgroup = 0x02;
  373. /// <summary>
  374. /// Returned by
  375. /// <see cref="GetType()">GetType()</see>
  376. /// if the resource this <tt>SmbFile</tt>
  377. /// represents is a server.
  378. /// </summary>
  379. public const int TypeServer = 0x04;
  380. /// <summary>
  381. /// Returned by
  382. /// <see cref="GetType()">GetType()</see>
  383. /// if the resource this <tt>SmbFile</tt>
  384. /// represents is a share.
  385. /// </summary>
  386. public const int TypeShare = 0x08;
  387. /// <summary>
  388. /// Returned by
  389. /// <see cref="GetType()">GetType()</see>
  390. /// if the resource this <tt>SmbFile</tt>
  391. /// represents is a named pipe.
  392. /// </summary>
  393. public const int TypeNamedPipe = 0x10;
  394. /// <summary>
  395. /// Returned by
  396. /// <see cref="GetType()">GetType()</see>
  397. /// if the resource this <tt>SmbFile</tt>
  398. /// represents is a printer.
  399. /// </summary>
  400. public const int TypePrinter = 0x20;
  401. /// <summary>
  402. /// Returned by
  403. /// <see cref="GetType()">GetType()</see>
  404. /// if the resource this <tt>SmbFile</tt>
  405. /// represents is a communications device.
  406. /// </summary>
  407. public const int TypeComm = 0x40;
  408. private string _canon;
  409. private string _share;
  410. private long _createTime;
  411. private long _lastModified;
  412. private int _attributes;
  413. private long _attrExpiration;
  414. private long _size;
  415. private long _sizeExpiration;
  416. private bool _isExists;
  417. private int _shareAccess = FileShareRead | FileShareWrite | FileShareDelete;
  418. private bool _enableDfs = Config.GetBoolean("jcifs.smb.client.enabledfs", false);
  419. private SmbComBlankResponse _blankResp;
  420. private DfsReferral _dfsReferral;
  421. protected internal static Dfs Dfs;
  422. internal NtlmPasswordAuthentication Auth;
  423. internal SmbTree Tree;
  424. internal string Unc;
  425. internal int Fid;
  426. internal int Type;
  427. internal bool Opened;
  428. internal int TreeNum;
  429. public bool EnableDfs
  430. {
  431. get { return _enableDfs; }
  432. set { _enableDfs = value; }
  433. }
  434. /// <summary>
  435. /// Constructs an SmbFile representing a resource on an SMB network such as
  436. /// a file or directory.
  437. /// </summary>
  438. /// <remarks>
  439. /// Constructs an SmbFile representing a resource on an SMB network such as
  440. /// a file or directory. See the description and examples of smb URLs above.
  441. /// </remarks>
  442. /// <param name="url">A URL string</param>
  443. /// <exception cref="System.UriFormatException">
  444. /// If the <code>parent</code> and <code>child</code> parameters
  445. /// do not follow the prescribed syntax
  446. /// </exception>
  447. public SmbFile(string url)
  448. : this(new Uri(url))
  449. {
  450. }
  451. /// <summary>
  452. /// Constructs an SmbFile representing a resource on an SMB network such
  453. /// as a file or directory.
  454. /// </summary>
  455. /// <remarks>
  456. /// Constructs an SmbFile representing a resource on an SMB network such
  457. /// as a file or directory. The second parameter is a relative path from
  458. /// the <code>parent SmbFile</code>. See the description above for examples
  459. /// of using the second <code>name</code> parameter.
  460. /// </remarks>
  461. /// <param name="context">A base <code>SmbFile</code></param>
  462. /// <param name="name">A path string relative to the <code>parent</code> paremeter</param>
  463. /// <exception cref="System.UriFormatException">
  464. /// If the <code>parent</code> and <code>child</code> parameters
  465. /// do not follow the prescribed syntax
  466. /// </exception>
  467. /// <exception cref="UnknownHostException">If the server or workgroup of the <tt>context</tt> file cannot be determined
  468. /// </exception>
  469. public SmbFile(SmbFile context, string name)
  470. : this(context.IsWorkgroup0()
  471. ? new Uri("smb://" + name)
  472. : new Uri(context.Url.AbsoluteUri + name),
  473. context.Auth)
  474. {
  475. this._enableDfs = context.EnableDfs;
  476. if (!context.IsWorkgroup0())
  477. {
  478. Addresses = context.Addresses;
  479. if (context._share != null)
  480. {
  481. Tree = context.Tree;
  482. _dfsReferral = context._dfsReferral;
  483. }
  484. }
  485. }
  486. /// <summary>
  487. /// Constructs an SmbFile representing a resource on an SMB network such
  488. /// as a file or directory.
  489. /// </summary>
  490. /// <remarks>
  491. /// Constructs an SmbFile representing a resource on an SMB network such
  492. /// as a file or directory. The second parameter is a relative path from
  493. /// the <code>parent</code>. See the description above for examples of
  494. /// using the second <code>chile</code> parameter.
  495. /// </remarks>
  496. /// <param name="context">A URL string</param>
  497. /// <param name="name">A path string relative to the <code>context</code> paremeter</param>
  498. /// <exception cref="System.UriFormatException">
  499. /// If the <code>context</code> and <code>name</code> parameters
  500. /// do not follow the prescribed syntax
  501. /// </exception>
  502. /*public SmbFile(string context, string name)
  503. : this(new Uri(new Uri(null, context), name))
  504. {
  505. }*/
  506. public SmbFile(string context, string name)
  507. : this(new Uri(context + name))
  508. {
  509. }
  510. /// <summary>
  511. /// Constructs an SmbFile representing a resource on an SMB network such
  512. /// as a file or directory.
  513. /// </summary>
  514. /// <remarks>
  515. /// Constructs an SmbFile representing a resource on an SMB network such
  516. /// as a file or directory.
  517. /// </remarks>
  518. /// <param name="url">A URL string</param>
  519. /// <param name="auth">The credentials the client should use for authentication</param>
  520. /// <exception cref="System.UriFormatException">If the <code>url</code> parameter does not follow the prescribed syntax
  521. /// </exception>
  522. public SmbFile(string url, NtlmPasswordAuthentication auth)
  523. : this(new Uri(url, UriKind.RelativeOrAbsolute), auth)
  524. {
  525. }
  526. /// <summary>Constructs an SmbFile representing a file on an SMB network.</summary>
  527. /// <remarks>
  528. /// Constructs an SmbFile representing a file on an SMB network. The
  529. /// <tt>shareAccess</tt> parameter controls what permissions other
  530. /// clients have when trying to access the same file while this instance
  531. /// is still open. This value is either <tt>FILE_NO_SHARE</tt> or any
  532. /// combination of <tt>FILE_SHARE_READ</tt>, <tt>FILE_SHARE_WRITE</tt>,
  533. /// and <tt>FILE_SHARE_DELETE</tt> logically OR'd together.
  534. /// </remarks>
  535. /// <param name="url">A URL string</param>
  536. /// <param name="auth">The credentials the client should use for authentication</param>
  537. /// <param name="shareAccess">Specifies what access other clients have while this file is open.
  538. /// </param>
  539. /// <exception cref="System.UriFormatException">If the <code>url</code> parameter does not follow the prescribed syntax
  540. /// </exception>
  541. public SmbFile(string url, NtlmPasswordAuthentication auth, int shareAccess)
  542. : this(new Uri(url), auth)
  543. {
  544. // Initially null; set by getUncPath; dir must end with '/'
  545. // Can be null
  546. // For getDfsPath() and getServerWithDfs()
  547. // Cannot be null
  548. // Initially null
  549. // Initially null; set by getUncPath; never ends with '/'
  550. // Initially 0; set by open()
  551. if ((shareAccess & ~(FileShareRead | FileShareWrite | FileShareDelete)) != 0)
  552. {
  553. throw new RuntimeException("Illegal shareAccess parameter");
  554. }
  555. this._shareAccess = shareAccess;
  556. }
  557. /// <summary>
  558. /// Constructs an SmbFile representing a resource on an SMB network such
  559. /// as a file or directory.
  560. /// </summary>
  561. /// <remarks>
  562. /// Constructs an SmbFile representing a resource on an SMB network such
  563. /// as a file or directory. The second parameter is a relative path from
  564. /// the <code>context</code>. See the description above for examples of
  565. /// using the second <code>name</code> parameter.
  566. /// </remarks>
  567. /// <param name="context">A URL string</param>
  568. /// <param name="name">A path string relative to the <code>context</code> paremeter</param>
  569. /// <param name="auth">The credentials the client should use for authentication</param>
  570. /// <exception cref="System.UriFormatException">
  571. /// If the <code>context</code> and <code>name</code> parameters
  572. /// do not follow the prescribed syntax
  573. /// </exception>
  574. public SmbFile(string context, string name, NtlmPasswordAuthentication auth)
  575. : this(new Uri(context + name), auth)
  576. {
  577. }
  578. /// <summary>
  579. /// Constructs an SmbFile representing a resource on an SMB network such
  580. /// as a file or directory.
  581. /// </summary>
  582. /// <remarks>
  583. /// Constructs an SmbFile representing a resource on an SMB network such
  584. /// as a file or directory. The second parameter is a relative path from
  585. /// the <code>context</code>. See the description above for examples of
  586. /// using the second <code>name</code> parameter. The <tt>shareAccess</tt>
  587. /// parameter controls what permissions other clients have when trying
  588. /// to access the same file while this instance is still open. This
  589. /// value is either <tt>FILE_NO_SHARE</tt> or any combination
  590. /// of <tt>FILE_SHARE_READ</tt>, <tt>FILE_SHARE_WRITE</tt>, and
  591. /// <tt>FILE_SHARE_DELETE</tt> logically OR'd together.
  592. /// </remarks>
  593. /// <param name="context">A URL string</param>
  594. /// <param name="name">A path string relative to the <code>context</code> paremeter</param>
  595. /// <param name="auth">The credentials the client should use for authentication</param>
  596. /// <param name="shareAccess">Specifies what access other clients have while this file is open.
  597. /// </param>
  598. /// <exception cref="System.UriFormatException">
  599. /// If the <code>context</code> and <code>name</code> parameters
  600. /// do not follow the prescribed syntax
  601. /// </exception>
  602. public SmbFile(string context,
  603. string name,
  604. NtlmPasswordAuthentication auth,
  605. int shareAccess)
  606. : this(new Uri(context + name), auth)
  607. {
  608. if ((shareAccess & ~(FileShareRead | FileShareWrite | FileShareDelete)) != 0)
  609. {
  610. throw new RuntimeException("Illegal shareAccess parameter");
  611. }
  612. this._shareAccess = shareAccess;
  613. }
  614. /// <summary>
  615. /// Constructs an SmbFile representing a resource on an SMB network such
  616. /// as a file or directory.
  617. /// </summary>
  618. /// <remarks>
  619. /// Constructs an SmbFile representing a resource on an SMB network such
  620. /// as a file or directory. The second parameter is a relative path from
  621. /// the <code>context</code>. See the description above for examples of
  622. /// using the second <code>name</code> parameter. The <tt>shareAccess</tt>
  623. /// parameter controls what permissions other clients have when trying
  624. /// to access the same file while this instance is still open. This
  625. /// value is either <tt>FILE_NO_SHARE</tt> or any combination
  626. /// of <tt>FILE_SHARE_READ</tt>, <tt>FILE_SHARE_WRITE</tt>, and
  627. /// <tt>FILE_SHARE_DELETE</tt> logically OR'd together.
  628. /// </remarks>
  629. /// <param name="context">A base <code>SmbFile</code></param>
  630. /// <param name="name">A path string relative to the <code>context</code> file path</param>
  631. /// <param name="shareAccess">Specifies what access other clients have while this file is open.
  632. /// </param>
  633. /// <exception cref="System.UriFormatException">
  634. /// If the <code>context</code> and <code>name</code> parameters
  635. /// do not follow the prescribed syntax
  636. /// </exception>
  637. /// <exception cref="UnknownHostException"></exception>
  638. public SmbFile(SmbFile context, string name, int shareAccess)
  639. : this(context.IsWorkgroup0()
  640. ? new Uri("smb://" + name)
  641. : new Uri(context.Url.AbsoluteUri + name),
  642. context.Auth)
  643. {
  644. if ((shareAccess & ~(FileShareRead | FileShareWrite | FileShareDelete)) != 0)
  645. {
  646. throw new RuntimeException("Illegal shareAccess parameter");
  647. }
  648. if (!context.IsWorkgroup0())
  649. {
  650. this.Addresses = context.Addresses;
  651. if (context._share != null || context.Tree != null)
  652. {
  653. Tree = context.Tree;
  654. _dfsReferral = context._dfsReferral;
  655. }
  656. }
  657. this._shareAccess = shareAccess;
  658. this._enableDfs = context.EnableDfs;
  659. }
  660. /// <summary>
  661. /// Constructs an SmbFile representing a resource on an SMB network such
  662. /// as a file or directory from a <tt>URL</tt> object.
  663. /// </summary>
  664. /// <remarks>
  665. /// Constructs an SmbFile representing a resource on an SMB network such
  666. /// as a file or directory from a <tt>URL</tt> object.
  667. /// </remarks>
  668. /// <param name="url">The URL of the target resource</param>
  669. protected SmbFile(Uri url)
  670. : this(url, new NtlmPasswordAuthentication(url.GetUserInfo()))
  671. {
  672. }
  673. /// <summary>
  674. /// Constructs an SmbFile representing a resource on an SMB network such
  675. /// as a file or directory from a <tt>URL</tt> object and an
  676. /// <tt>NtlmPasswordAuthentication</tt> object.
  677. /// </summary>
  678. /// <remarks>
  679. /// Constructs an SmbFile representing a resource on an SMB network such
  680. /// as a file or directory from a <tt>URL</tt> object and an
  681. /// <tt>NtlmPasswordAuthentication</tt> object.
  682. /// </remarks>
  683. /// <param name="url">The URL of the target resource</param>
  684. /// <param name="auth">The credentials the client should use for authentication</param>
  685. public SmbFile(Uri url, NtlmPasswordAuthentication auth)
  686. {
  687. this.Auth = auth ?? new NtlmPasswordAuthentication(url.GetUserInfo());
  688. Url = url;
  689. GetUncPath0();
  690. }
  691. /// <exception cref="System.UriFormatException"></exception>
  692. /// <exception cref="UnknownHostException"></exception>
  693. internal SmbFile(SmbFile context,
  694. string name,
  695. int type,
  696. int attributes,
  697. long createTime,
  698. long lastModified,
  699. long size)
  700. : this(context.IsWorkgroup0()
  701. ? new Uri("smb://" + name + "/")
  702. : new Uri(context.Url.AbsoluteUri + name + ((attributes & AttrDirectory) > 0
  703. ? "/"
  704. : string.Empty)))
  705. {
  706. Auth = context.Auth;
  707. if (context._share != null)
  708. {
  709. Tree = context.Tree;
  710. _dfsReferral = context._dfsReferral;
  711. }
  712. int last = name.Length - 1;
  713. if (name[last] == '/')
  714. {
  715. name = Runtime.Substring(name, 0, last);
  716. }
  717. if (context._share == null)
  718. {
  719. Unc = "\\";
  720. }
  721. else
  722. {
  723. if (context.Unc.Equals("\\"))
  724. {
  725. Unc = '\\' + name;
  726. }
  727. else
  728. {
  729. Unc = context.Unc + '\\' + name;
  730. }
  731. }
  732. if (!context.IsWorkgroup0())
  733. {
  734. Addresses = context.Addresses;
  735. }
  736. this._enableDfs = context.EnableDfs;
  737. this.Type = type;
  738. this._attributes = attributes;
  739. this._createTime = createTime;
  740. this._lastModified = lastModified;
  741. this._size = size;
  742. _isExists = true;
  743. _attrExpiration = _sizeExpiration = Runtime.CurrentTimeMillis() + AttrExpirationPeriod;
  744. }
  745. private SmbComBlankResponse Blank_resp()
  746. {
  747. if (_blankResp == null)
  748. {
  749. _blankResp = new SmbComBlankResponse();
  750. }
  751. return _blankResp;
  752. }
  753. /// <exception cref="SharpCifs.Smb.SmbException"></exception>
  754. internal virtual void ResolveDfs(ServerMessageBlock request)
  755. {
  756. if (!_enableDfs)
  757. {
  758. Connect0();
  759. return;
  760. }
  761. if (request is SmbComClose)
  762. {
  763. return;
  764. }
  765. Connect0();
  766. DfsReferral dr = Dfs.Resolve(Tree.Session.transport.TconHostName, Tree.Share, Unc, Auth);
  767. if (dr != null)
  768. {
  769. string service = null;
  770. if (request != null)
  771. {
  772. switch (request.Command)
  773. {
  774. case ServerMessageBlock.SmbComTransaction:
  775. case ServerMessageBlock.SmbComTransaction2:
  776. {
  777. switch (((SmbComTransaction)request).SubCommand & 0xFF)
  778. {
  779. case SmbComTransaction.Trans2GetDfsReferral:
  780. {
  781. break;
  782. }
  783. default:
  784. {
  785. service = "A:";
  786. break;
  787. }
  788. }
  789. break;
  790. }
  791. default:
  792. {
  793. service = "A:";
  794. break;
  795. }
  796. }
  797. }
  798. DfsReferral start = dr;
  799. SmbException se = null;
  800. do
  801. {
  802. try
  803. {
  804. if (Log.Level >= 2)
  805. {
  806. Log.WriteLine("DFS redirect: " + dr);
  807. }
  808. UniAddress addr = UniAddress.GetByName(dr.Server);
  809. SmbTransport trans = SmbTransport.GetSmbTransport(addr, Url.Port);
  810. trans.Connect();
  811. Tree = trans.GetSmbSession(Auth).GetSmbTree(dr.Share, service);
  812. if (dr != start && dr.Key != null)
  813. {
  814. dr.Map.Put(dr.Key, dr);
  815. }
  816. se = null;
  817. break;
  818. }
  819. catch (IOException ioe)
  820. {
  821. if (ioe is SmbException)
  822. {
  823. se = (SmbException)ioe;
  824. }
  825. else
  826. {
  827. se = new SmbException(dr.Server, ioe);
  828. }
  829. }
  830. dr = dr.Next;
  831. }
  832. while (dr != start);
  833. if (se != null)
  834. {
  835. throw se;
  836. }
  837. if (Log.Level >= 3)
  838. {
  839. Log.WriteLine(dr);
  840. }
  841. _dfsReferral = dr;
  842. if (dr.PathConsumed < 0)
  843. {
  844. dr.PathConsumed = 0;
  845. }
  846. else
  847. {
  848. if (dr.PathConsumed > Unc.Length)
  849. {
  850. dr.PathConsumed = Unc.Length;
  851. }
  852. }
  853. string dunc = Runtime.Substring(Unc, dr.PathConsumed);
  854. if (dunc.Equals(string.Empty))
  855. {
  856. dunc = "\\";
  857. }
  858. if (!dr.Path.Equals(string.Empty))
  859. {
  860. dunc = "\\" + dr.Path + dunc;
  861. }
  862. Unc = dunc;
  863. if (request != null
  864. && request.Path != null
  865. && request.Path.EndsWith("\\")
  866. && dunc.EndsWith("\\") == false)
  867. {
  868. dunc += "\\";
  869. }
  870. if (request != null)
  871. {
  872. request.Path = dunc;
  873. request.Flags2 |= SmbConstants.Flags2ResolvePathsInDfs;
  874. }
  875. }
  876. else
  877. {
  878. if (Tree.InDomainDfs
  879. && !(request is NtTransQuerySecurityDesc)
  880. && !(request is SmbComClose)
  881. && !(request is SmbComFindClose2))
  882. {
  883. throw new SmbException(NtStatus.NtStatusNotFound, false);
  884. }
  885. if (request != null)
  886. {
  887. request.Flags2 &= ~SmbConstants.Flags2ResolvePathsInDfs;
  888. }
  889. }
  890. }
  891. /// <exception cref="SharpCifs.Smb.SmbException"></exception>
  892. internal virtual void Send(ServerMessageBlock request, ServerMessageBlock response)
  893. {
  894. for (;;)
  895. {
  896. ResolveDfs(request);
  897. try
  898. {
  899. Tree.Send(request, response);
  900. break;
  901. }
  902. catch (DfsReferral dre)
  903. {
  904. if (dre.ResolveHashes)
  905. {
  906. throw;
  907. }
  908. request.Reset();
  909. }
  910. }
  911. }
  912. internal static string QueryLookup(string query, string param)
  913. {
  914. char[] instr = query.ToCharArray();
  915. int i;
  916. int ch;
  917. int st;
  918. int eq;
  919. st = eq = 0;
  920. for (i = 0; i < instr.Length; i++)
  921. {
  922. ch = instr[i];
  923. if (ch == '&')
  924. {
  925. if (eq > st)
  926. {
  927. string p = new string(instr, st, eq - st);
  928. if (Runtime.EqualsIgnoreCase(p, param))
  929. {
  930. eq++;
  931. return new string(instr, eq, i - eq);
  932. }
  933. }
  934. st = i + 1;
  935. }
  936. else
  937. {
  938. if (ch == '=')
  939. {
  940. eq = i;
  941. }
  942. }
  943. }
  944. if (eq > st)
  945. {
  946. string p = new string(instr, st, eq - st);
  947. if (Runtime.EqualsIgnoreCase(p, param))
  948. {
  949. eq++;
  950. return new string(instr, eq, instr.Length - eq);
  951. }
  952. }
  953. return null;
  954. }
  955. internal UniAddress[] Addresses;
  956. internal int AddressIndex;
  957. /// <exception cref="UnknownHostException"></exception>
  958. internal virtual UniAddress GetAddress()
  959. {
  960. if (AddressIndex == 0)
  961. {
  962. return GetFirstAddress();
  963. }
  964. return Addresses[AddressIndex - 1];
  965. }
  966. /// <exception cref="UnknownHostException"></exception>
  967. internal virtual UniAddress GetFirstAddress()
  968. {
  969. AddressIndex = 0;
  970. string host = Url.GetHost();
  971. string path = Url.AbsolutePath;
  972. string query = Url.GetQuery();
  973. if (Addresses != null && Addresses.Length > 0)
  974. {
  975. return GetNextAddress();
  976. }
  977. if (query != null)
  978. {
  979. string server = QueryLookup(query, "server");
  980. if (!string.IsNullOrEmpty(server))
  981. {
  982. Addresses = new UniAddress[1];
  983. Addresses[0] = UniAddress.GetByName(server);
  984. return GetNextAddress();
  985. }
  986. string address = QueryLookup(query, "address");
  987. if (!string.IsNullOrEmpty(address))
  988. {
  989. byte[] ip = Extensions.GetAddressByName(address).GetAddressBytes();
  990. Addresses = new UniAddress[1];
  991. //addresses[0] = new UniAddress(IPAddress.Parse(host, ip));
  992. Addresses[0] = new UniAddress(IPAddress.Parse(host));
  993. return GetNextAddress();
  994. }
  995. }
  996. if (host.Length == 0)
  997. {
  998. try
  999. {
  1000. NbtAddress addr = NbtAddress.GetByName(NbtAddress.MasterBrowserName, 0x01, null);
  1001. Addresses = new UniAddress[1];
  1002. Addresses[0] = UniAddress.GetByName(addr.GetHostAddress());
  1003. }
  1004. catch (UnknownHostException uhe)
  1005. {
  1006. NtlmPasswordAuthentication.InitDefaults();
  1007. if (NtlmPasswordAuthentication.DefaultDomain.Equals("?"))
  1008. {
  1009. throw;
  1010. }
  1011. Addresses = UniAddress.GetAllByName(NtlmPasswordAuthentication.DefaultDomain,
  1012. true);
  1013. }
  1014. }
  1015. else
  1016. {
  1017. if (path.Length == 0 || path.Equals("/"))
  1018. {
  1019. Addresses = UniAddress.GetAllByName(host, true);
  1020. }
  1021. else
  1022. {
  1023. Addresses = UniAddress.GetAllByName(host, false);
  1024. }
  1025. }
  1026. return GetNextAddress();
  1027. }
  1028. internal virtual UniAddress GetNextAddress()
  1029. {
  1030. UniAddress addr = null;
  1031. if (AddressIndex < Addresses.Length)
  1032. {
  1033. addr = Addresses[AddressIndex++];
  1034. }
  1035. return addr;
  1036. }
  1037. internal virtual bool HasNextAddress()
  1038. {
  1039. return AddressIndex < Addresses.Length;
  1040. }
  1041. /// <exception cref="SharpCifs.Smb.SmbException"></exception>
  1042. internal virtual void Connect0()
  1043. {
  1044. try
  1045. {
  1046. Connect();
  1047. }
  1048. catch (UnknownHostException uhe)
  1049. {
  1050. throw new SmbException("Failed to connect to server", uhe);
  1051. }
  1052. catch (SmbException se)
  1053. {
  1054. throw;
  1055. }
  1056. catch (IOException ioe)
  1057. {
  1058. throw new SmbException("Failed to connect to server", ioe);
  1059. }
  1060. }
  1061. /// <exception cref="System.IO.IOException"></exception>
  1062. internal virtual void DoConnect()
  1063. {
  1064. SmbTransport trans;
  1065. UniAddress addr;
  1066. addr = GetAddress();
  1067. if (Tree != null && Tree.Session.transport.Address.Equals(addr))
  1068. {
  1069. trans = Tree.Session.transport;
  1070. }
  1071. else
  1072. {
  1073. trans = SmbTransport.GetSmbTransport(addr, Url.Port);
  1074. Tree = trans.GetSmbSession(Auth).GetSmbTree(_share, null);
  1075. }
  1076. string hostName = GetServerWithDfs();
  1077. if (_enableDfs)
  1078. {
  1079. Tree.InDomainDfs = Dfs.Resolve(hostName, Tree.Share, null, Auth) != null;
  1080. }
  1081. if (Tree.InDomainDfs)
  1082. {
  1083. Tree.ConnectionState = 2;
  1084. }
  1085. try
  1086. {
  1087. if (Log.Level >= 3)
  1088. {
  1089. Log.WriteLine("doConnect: " + addr);
  1090. }
  1091. Tree.TreeConnect(null, null);
  1092. }
  1093. catch (SmbAuthException sae)
  1094. {
  1095. NtlmPasswordAuthentication a;
  1096. SmbSession ssn;
  1097. if (_share == null)
  1098. {
  1099. // IPC$ - try "anonymous" credentials
  1100. ssn = trans.GetSmbSession(NtlmPasswordAuthentication.Null);
  1101. Tree = ssn.GetSmbTree(null, null);
  1102. Tree.TreeConnect(null, null);
  1103. }
  1104. else
  1105. {
  1106. if ((a = NtlmAuthenticator.RequestNtlmPasswordAuthentication(Url.ToString(), sae))
  1107. != null)
  1108. {
  1109. Auth = a;
  1110. ssn = trans.GetSmbSession(Auth);
  1111. Tree = ssn.GetSmbTree(_share, null);
  1112. Tree.InDomainDfs = Dfs.Resolve(hostName, Tree.Share, null, Auth) != null;
  1113. if (Tree.InDomainDfs)
  1114. {
  1115. Tree.ConnectionState = 2;
  1116. }
  1117. Tree.TreeConnect(null, null);
  1118. }
  1119. else
  1120. {
  1121. if (Log.Level >= 1 && HasNextAddress())
  1122. {
  1123. Runtime.PrintStackTrace(sae, Log);
  1124. }
  1125. throw;
  1126. }
  1127. }
  1128. }
  1129. }
  1130. /// <summary>It is not necessary to call this method directly.</summary>
  1131. /// <remarks>
  1132. /// It is not necessary to call this method directly. This is the
  1133. /// <tt>URLConnection</tt> implementation of <tt>connect()</tt>.
  1134. /// </remarks>
  1135. /// <exception cref="System.IO.IOException"></exception>
  1136. public void Connect()
  1137. {
  1138. SmbTransport trans;
  1139. SmbSession ssn;
  1140. UniAddress addr;
  1141. if (IsConnected())
  1142. {
  1143. return;
  1144. }
  1145. GetUncPath0();
  1146. GetFirstAddress();
  1147. for (;;)
  1148. {
  1149. try
  1150. {
  1151. DoConnect();
  1152. return;
  1153. }
  1154. catch (SmbAuthException sae)
  1155. {
  1156. throw;
  1157. }
  1158. catch (SmbException se)
  1159. {
  1160. // Prevents account lockout on servers with multiple IPs
  1161. if (GetNextAddress() == null)
  1162. {
  1163. throw;
  1164. }
  1165. else
  1166. {
  1167. RemoveCurrentAddress();
  1168. }
  1169. if (Log.Level >= 3)
  1170. {
  1171. Runtime.PrintStackTrace(se, Log);
  1172. }
  1173. }
  1174. }
  1175. }
  1176. internal virtual bool IsConnected()
  1177. {
  1178. return Tree != null && Tree.ConnectionState == 2;
  1179. }
  1180. /// <exception cref="SharpCifs.Smb.SmbException"></exception>
  1181. internal virtual int Open0(int flags, int access, int attrs, int options)
  1182. {
  1183. int f;
  1184. Connect0();
  1185. if (Log.Level >= 3)
  1186. {
  1187. Log.WriteLine("open0: " + Unc);
  1188. }
  1189. if (Tree.Session.transport.HasCapability(SmbConstants.CapNtSmbs))
  1190. {
  1191. SmbComNtCreateAndXResponse response = new SmbComNtCreateAndXResponse();
  1192. SmbComNtCreateAndX request = new SmbComNtCreateAndX(Unc,
  1193. flags,
  1194. access,
  1195. _shareAccess,
  1196. attrs,
  1197. options,
  1198. null);
  1199. if (this is SmbNamedPipe)
  1200. {
  1201. request.Flags0 |= 0x16;
  1202. request.DesiredAccess |= 0x20000;
  1203. response.IsExtended = true;
  1204. }
  1205. Send(request, response);
  1206. f = response.Fid;
  1207. _attributes = response.ExtFileAttributes & AttrGetMask;
  1208. _attrExpiration = Runtime.CurrentTimeMillis() + AttrExpirationPeriod;
  1209. _isExists = true;
  1210. }
  1211. else
  1212. {
  1213. SmbComOpenAndXResponse response = new SmbComOpenAndXResponse();
  1214. Send(new SmbComOpenAndX(Unc, access, flags, null), response);
  1215. f = response.Fid;
  1216. }
  1217. return f;
  1218. }
  1219. /// <exception cref="SharpCifs.Smb.SmbException"></exception>
  1220. internal virtual void Open(int flags, int access, int attrs, int options)
  1221. {
  1222. if (IsOpen())
  1223. {
  1224. return;
  1225. }
  1226. Fid = Open0(flags, access, attrs, options);
  1227. Opened = true;
  1228. TreeNum = Tree.TreeNum;
  1229. }
  1230. internal virtual bool IsOpen()
  1231. {
  1232. bool ans = Opened && IsConnected() && TreeNum == Tree.TreeNum;
  1233. return ans;
  1234. }
  1235. /// <exception cref="SharpCifs.Smb.SmbException"></exception>
  1236. internal virtual void Close(int f, long lastWriteTime)
  1237. {
  1238. if (Log.Level >= 3)
  1239. {
  1240. Log.WriteLine("close: " + f);
  1241. }
  1242. Send(new SmbComClose(f, lastWriteTime), Blank_resp());
  1243. }
  1244. /// <exception cref="SharpCifs.Smb.SmbException"></exception>
  1245. internal virtual void Close(long lastWriteTime)
  1246. {
  1247. if (IsOpen() == false)
  1248. {
  1249. return;
  1250. }
  1251. Close(Fid, lastWriteTime);
  1252. Opened = false;
  1253. }
  1254. /// <exception cref="SharpCifs.Smb.SmbException"></exception>
  1255. internal virtual void Close()
  1256. {
  1257. Close(0L);
  1258. }
  1259. /// <summary>
  1260. /// Returns the <tt>NtlmPasswordAuthentication</tt> object used as
  1261. /// credentials with this file or pipe.
  1262. /// </summary>
  1263. /// <remarks>
  1264. /// Returns the <tt>NtlmPasswordAuthentication</tt> object used as
  1265. /// credentials with this file or pipe. This can be used to retrieve the
  1266. /// username for example:
  1267. /// <tt>
  1268. /// String username = f.getPrincipal().getName();
  1269. /// </tt>
  1270. /// The <tt>Principal</tt> object returned will never be <tt>null</tt>
  1271. /// however the username can be <tt>null</tt> indication anonymous
  1272. /// credentials were used (e.g. some IPC$ services).
  1273. /// </remarks>
  1274. public virtual Principal GetPrincipal()
  1275. {
  1276. return Auth;
  1277. }
  1278. /// <summary>Returns the last component of the target URL.</summary>
  1279. /// <remarks>
  1280. /// Returns the last component of the target URL. This will
  1281. /// effectively be the name of the file or directory represented by this
  1282. /// <code>SmbFile</code> or in the case of URLs that only specify a server
  1283. /// or workgroup, the server or workgroup will be returned. The name of
  1284. /// the root URL <code>smb://</code> is also <code>smb://</code>. If this
  1285. /// <tt>SmbFile</tt> refers to a workgroup, server, share, or directory,
  1286. /// the name will include a trailing slash '/' so that composing new
  1287. /// <tt>SmbFile</tt>s will maintain the trailing slash requirement.
  1288. /// </remarks>
  1289. /// <returns>
  1290. /// The last component of the URL associated with this SMB
  1291. /// resource or <code>smb://</code> if the resource is <code>smb://</code>
  1292. /// itself.
  1293. /// </returns>
  1294. public virtual string GetName()
  1295. {
  1296. GetUncPath0();
  1297. if (_canon.Length > 1)
  1298. {
  1299. int i = _canon.Length - 2;
  1300. while (_canon[i] != '/')
  1301. {
  1302. i--;
  1303. }
  1304. return Runtime.Substring(_canon, i + 1);
  1305. }
  1306. if (_share != null)
  1307. {
  1308. return _share + '/';
  1309. }
  1310. if (Url.GetHost().Length > 0)
  1311. {
  1312. return Url.GetHost() + '/';
  1313. }
  1314. return "smb://";
  1315. }
  1316. /// <summary>
  1317. /// Everything but the last component of the URL representing this SMB
  1318. /// resource is effectivly it's parent.
  1319. /// </summary>
  1320. /// <remarks>
  1321. /// Everything but the last component of the URL representing this SMB
  1322. /// resource is effectivly it's parent. The root URL <code>smb://</code>
  1323. /// does not have a parent. In this case <code>smb://</code> is returned.
  1324. /// </remarks>
  1325. /// <returns>
  1326. /// The parent directory of this SMB resource or
  1327. /// <code>smb://</code> if the resource refers to the root of the URL
  1328. /// hierarchy which incedentally is also <code>smb://</code>.
  1329. /// </returns>
  1330. public virtual string GetParent()
  1331. {
  1332. string str = Url.Authority;
  1333. if (str.Length > 0)
  1334. {
  1335. StringBuilder sb = new StringBuilder("smb://");
  1336. sb.Append(str);
  1337. GetUncPath0();
  1338. if (_canon.Length > 1)
  1339. {
  1340. sb.Append(_canon);
  1341. }
  1342. else
  1343. {
  1344. sb.Append('/');
  1345. }
  1346. str = sb.ToString();
  1347. int i = str.Length - 2;
  1348. while (str[i] != '/')
  1349. {
  1350. i--;
  1351. }
  1352. return Runtime.Substring(str, 0, i + 1);
  1353. }
  1354. return "smb://";
  1355. }
  1356. /// <summary>Returns the full uncanonicalized URL of this SMB resource.</summary>
  1357. /// <remarks>
  1358. /// Returns the full uncanonicalized URL of this SMB resource. An
  1359. /// <code>SmbFile</code> constructed with the result of this method will
  1360. /// result in an <code>SmbFile</code> that is equal to the original.
  1361. /// </remarks>
  1362. /// <returns>The uncanonicalized full URL of this SMB resource.</returns>
  1363. public virtual string GetPath()
  1364. {
  1365. return Url.ToString();
  1366. }
  1367. internal virtual string GetUncPath0()
  1368. {
  1369. if (Unc == null)
  1370. {
  1371. char[] instr = Url.LocalPath.ToCharArray();
  1372. char[] outstr = new char[instr.Length];
  1373. int length = instr.Length;
  1374. int i;
  1375. int o;
  1376. int state;
  1377. state = 0;
  1378. o = 0;
  1379. for (i = 0; i < length; i++)
  1380. {
  1381. switch (state)
  1382. {
  1383. case 0:
  1384. {
  1385. if (instr[i] != '/')
  1386. {
  1387. return null;
  1388. }
  1389. outstr[o++] = instr[i];
  1390. state = 1;
  1391. break;
  1392. }
  1393. case 1:
  1394. {
  1395. if (instr[i] == '/')
  1396. {
  1397. break;
  1398. }
  1399. if (instr[i] == '.' && ((i + 1) >= length || instr[i + 1] == '/'))
  1400. {
  1401. i++;
  1402. break;
  1403. }
  1404. if ((i + 1) < length
  1405. && instr[i] == '.'
  1406. && instr[i + 1] == '.'
  1407. && ((i + 2) >= length || instr[i + 2] == '/'))
  1408. {
  1409. i += 2;
  1410. if (o == 1)
  1411. {
  1412. break;
  1413. }
  1414. do
  1415. {
  1416. o--;
  1417. }
  1418. while (o > 1 && outstr[o - 1] != '/');
  1419. break;
  1420. }
  1421. state = 2;
  1422. goto case 2;
  1423. }
  1424. case 2:
  1425. {
  1426. if (instr[i] == '/')
  1427. {
  1428. state = 1;
  1429. }
  1430. outstr[o++] = instr[i];
  1431. break;
  1432. }
  1433. }
  1434. }
  1435. _canon = new string(outstr, 0, o);
  1436. if (o > 1)
  1437. {
  1438. o--;
  1439. i = _canon.IndexOf('/', 1);
  1440. if (i < 0)
  1441. {
  1442. _share = Runtime.Substring(_canon, 1);
  1443. Unc = "\\";
  1444. }
  1445. else
  1446. {
  1447. if (i == o)
  1448. {
  1449. _share = Runtime.Substring(_canon, 1, i);
  1450. Unc = "\\";
  1451. }
  1452. else
  1453. {
  1454. _share = Runtime.Substring(_canon, 1, i);
  1455. Unc = Runtime.Substring(_canon, i, outstr[o] == '/' ? o : o + 1);
  1456. Unc = Unc.Replace('/', '\\');
  1457. }
  1458. }
  1459. }
  1460. else
  1461. {
  1462. _share = null;
  1463. Unc = "\\";
  1464. }
  1465. }
  1466. return Unc;
  1467. }
  1468. /// <summary>Retuns the Windows UNC style path with backslashs intead of forward slashes.
  1469. /// </summary>
  1470. /// <remarks>Retuns the Windows UNC style path with backslashs intead of forward slashes.
  1471. /// </remarks>
  1472. /// <returns>The UNC path.</returns>
  1473. public virtual string GetUncPath()
  1474. {
  1475. GetUncPath0();
  1476. if (_share == null)
  1477. {
  1478. return "\\\\" + Url.GetHost();
  1479. }
  1480. return "\\\\" + Url.GetHost() + _canon.Replace('/', '\\');
  1481. }
  1482. /// <summary>
  1483. /// Returns the full URL of this SMB resource with '.' and '..' components
  1484. /// factored out.
  1485. /// </summary>
  1486. /// <remarks>
  1487. /// Returns the full URL of this SMB resource with '.' and '..' components
  1488. /// factored out. An <code>SmbFile</code> constructed with the result of
  1489. /// this method will result in an <code>SmbFile</code> that is equal to
  1490. /// the original.
  1491. /// </remarks>
  1492. /// <returns>The canonicalized URL of this SMB resource.</returns>
  1493. public virtual string GetCanonicalPath()
  1494. {
  1495. string str = Url.Authority;
  1496. GetUncPath0();
  1497. if (str.Length > 0)
  1498. {
  1499. return "smb://" + Url.Authority + _canon;
  1500. }
  1501. return "smb://";
  1502. }
  1503. /// <summary>Retrieves the share associated with this SMB resource.</summary>
  1504. /// <remarks>
  1505. /// Retrieves the share associated with this SMB resource. In
  1506. /// the case of <code>smb://</code>, <code>smb://workgroup/</code>,
  1507. /// and <code>smb://server/</code> URLs which do not specify a share,
  1508. /// <code>null</code> will be returned.
  1509. /// </remarks>
  1510. /// <returns>The share component or <code>null</code> if there is no share</returns>
  1511. public virtual string GetShare()
  1512. {
  1513. return _share;
  1514. }
  1515. internal virtual string GetServerWithDfs()
  1516. {
  1517. if (_dfsReferral != null)
  1518. {
  1519. return _dfsReferral.Server;
  1520. }
  1521. return GetServer();
  1522. }
  1523. /// <summary>Retrieve the hostname of the server for this SMB resource.</summary>
  1524. /// <remarks>
  1525. /// Retrieve the hostname of the server for this SMB resource. If this
  1526. /// <code>SmbFile</code> references a workgroup, the name of the workgroup
  1527. /// is returned. If this <code>SmbFile</code> refers to the root of this
  1528. /// SMB network hierarchy, <code>null</code> is returned.
  1529. /// </remarks>
  1530. /// <returns>
  1531. /// The server or workgroup name or <code>null</code> if this
  1532. /// <code>SmbFile</code> refers to the root <code>smb://</code> resource.
  1533. /// </returns>
  1534. public virtual string GetServer()
  1535. {
  1536. string str = Url.GetHost();
  1537. if (str.Length == 0)
  1538. {
  1539. return null;
  1540. }
  1541. return str;
  1542. }
  1543. /// <summary>Returns type of of object this <tt>SmbFile</tt> represents.</summary>
  1544. /// <remarks>Returns type of of object this <tt>SmbFile</tt> represents.</remarks>
  1545. /// <returns>
  1546. /// <tt>TYPE_FILESYSTEM, TYPE_WORKGROUP, TYPE_SERVER, TYPE_SHARE,
  1547. /// TYPE_PRINTER, TYPE_NAMED_PIPE</tt>, or <tt>TYPE_COMM</tt>.
  1548. /// </returns>
  1549. /// <exception cref="SharpCifs.Smb.SmbException"></exception>
  1550. public new virtual int GetType()
  1551. {
  1552. if (Type == 0)
  1553. {
  1554. if (GetUncPath0().Length > 1)
  1555. {
  1556. Type = TypeFilesystem;
  1557. }
  1558. else
  1559. {
  1560. if (_share != null)
  1561. {
  1562. // treeConnect good enough to test service type
  1563. Connect0();
  1564. if (_share.Equals("IPC$"))
  1565. {
  1566. Type = TypeNamedPipe;
  1567. }
  1568. else
  1569. {
  1570. if (Tree.Service.Equals("LPT1:"))
  1571. {
  1572. Type = TypePrinter;
  1573. }
  1574. else
  1575. {
  1576. if (Tree.Service.Equals("COMM"))
  1577. {
  1578. Type = TypeComm;
  1579. }
  1580. else
  1581. {
  1582. Type = TypeShare;
  1583. }
  1584. }
  1585. }
  1586. }
  1587. else
  1588. {
  1589. if (string.IsNullOrEmpty(Url.Authority))
  1590. {
  1591. Type = TypeWorkgroup;
  1592. }
  1593. else
  1594. {
  1595. UniAddress addr;
  1596. try
  1597. {
  1598. addr = GetAddress();
  1599. }
  1600. catch (UnknownHostException uhe)
  1601. {
  1602. throw new SmbException(Url.ToString(), uhe);
  1603. }
  1604. if (addr.GetAddress() is NbtAddress)
  1605. {
  1606. int code = ((NbtAddress)addr.GetAddress()).GetNameType();
  1607. if (code == 0x1d || code == 0x1b)
  1608. {
  1609. Type = TypeWorkgroup;
  1610. return Type;
  1611. }
  1612. }
  1613. Type = TypeServer;
  1614. }
  1615. }
  1616. }
  1617. }
  1618. return Type;
  1619. }
  1620. /// <exception cref="UnknownHostException"></exception>
  1621. internal virtual bool IsWorkgroup0()
  1622. {
  1623. if (Type == TypeWorkgroup || Url.GetHost().Length == 0)
  1624. {
  1625. Type = TypeWorkgroup;
  1626. return true;
  1627. }
  1628. GetUncPath0();
  1629. if (_share == null)
  1630. {
  1631. UniAddress addr = GetAddress();
  1632. if (addr.GetAddress() is NbtAddress)
  1633. {
  1634. int code = ((NbtAddress)addr.GetAddress()).GetNameType();
  1635. if (code == 0x1d || code == 0x1b)
  1636. {
  1637. Type = TypeWorkgroup;
  1638. return true;
  1639. }
  1640. }
  1641. Type = TypeServer;
  1642. }
  1643. return false;
  1644. }
  1645. /// <exception cref="SharpCifs.Smb.SmbException"></exception>
  1646. internal virtual IInfo QueryPath(string path, int infoLevel)
  1647. {
  1648. Connect0();
  1649. if (Log.Level >= 3)
  1650. {
  1651. Log.WriteLine("queryPath: " + path);
  1652. }
  1653. if (Tree.Session.transport.HasCapability(SmbConstants.CapNtSmbs))
  1654. {
  1655. Trans2QueryPathInformationResponse response
  1656. = new Trans2QueryPathInformationResponse(infoLevel);
  1657. Send(new Trans2QueryPathInformation(path, infoLevel), response);
  1658. return response.Info;
  1659. }
  1660. else
  1661. {
  1662. SmbComQueryInformationResponse response
  1663. = new SmbComQueryInformationResponse(Tree.Session.transport.Server.ServerTimeZone
  1664. * 1000
  1665. * 60L);
  1666. Send(new SmbComQueryInformation(path), response);
  1667. return response;
  1668. }
  1669. }
  1670. /// <summary>Tests to see if the SMB resource exists.</summary>
  1671. /// <remarks>
  1672. /// Tests to see if the SMB resource exists. If the resource refers
  1673. /// only to a server, this method determines if the server exists on the
  1674. /// network and is advertising SMB services. If this resource refers to
  1675. /// a workgroup, this method determines if the workgroup name is valid on
  1676. /// the local SMB network. If this <code>SmbFile</code> refers to the root
  1677. /// <code>smb://</code> resource <code>true</code> is always returned. If
  1678. /// this <code>SmbFile</code> is a traditional file or directory, it will
  1679. /// be queried for on the specified server as expected.
  1680. /// </remarks>
  1681. /// <returns>
  1682. /// <code>true</code> if the resource exists or is alive or
  1683. /// <code>false</code> otherwise
  1684. /// </returns>
  1685. /// <exception cref="SharpCifs.Smb.SmbException"></exception>
  1686. public virtual bool Exists()
  1687. {
  1688. if (_attrExpiration > Runtime.CurrentTimeMillis())
  1689. {
  1690. return _isExists;
  1691. }
  1692. _attributes = AttrReadonly | AttrDirectory;
  1693. _createTime = 0L;
  1694. _lastModified = 0L;
  1695. _isExists = false;
  1696. try
  1697. {
  1698. if (Url.GetHost().Length == 0)
  1699. {
  1700. }
  1701. else
  1702. {
  1703. if (_share == null)
  1704. {
  1705. if (GetType() == TypeWorkgroup)
  1706. {
  1707. UniAddress.GetByName(Url.GetHost(), true);
  1708. }
  1709. else
  1710. {
  1711. UniAddress.GetByName(Url.GetHost()).GetHostName();
  1712. }
  1713. }
  1714. else
  1715. {
  1716. if (GetUncPath0().Length == 1 || Runtime.EqualsIgnoreCase(_share, "IPC$"))
  1717. {
  1718. Connect0();
  1719. }
  1720. else
  1721. {
  1722. // treeConnect is good enough
  1723. IInfo info = QueryPath(GetUncPath0(),
  1724. Trans2QueryPathInformationResponse.SMB_QUERY_FILE_BASIC_INFO);
  1725. _attributes = info.GetAttributes();
  1726. _createTime = info.GetCreateTime();
  1727. _lastModified = info.GetLastWriteTime();
  1728. }
  1729. }
  1730. }
  1731. _isExists = true;
  1732. }
  1733. catch (UnknownHostException)
  1734. {
  1735. }
  1736. catch (SmbException se)
  1737. {
  1738. switch (se.GetNtStatus())
  1739. {
  1740. case NtStatus.NtStatusNoSuchFile:
  1741. case NtStatus.NtStatusObjectNameInvalid:
  1742. case NtStatus.NtStatusObjectNameNotFound:
  1743. case NtStatus.NtStatusObjectPathNotFound:
  1744. {
  1745. break;
  1746. }
  1747. default:
  1748. {
  1749. throw;
  1750. }
  1751. }
  1752. }
  1753. _attrExpiration = Runtime.CurrentTimeMillis() + AttrExpirationPeriod;
  1754. return _isExists;
  1755. }
  1756. /// <summary>
  1757. /// Tests to see if the file this <code>SmbFile</code> represents can be
  1758. /// read.
  1759. /// </summary>
  1760. /// <remarks>
  1761. /// Tests to see if the file this <code>SmbFile</code> represents can be
  1762. /// read. Because any file, directory, or other resource can be read if it
  1763. /// exists, this method simply calls the <code>exists</code> method.
  1764. /// </remarks>
  1765. /// <returns><code>true</code> if the file is read-only</returns>
  1766. /// <exception cref="SharpCifs.Smb.SmbException"></exception>
  1767. public virtual bool CanRead()
  1768. {
  1769. if (GetType() == TypeNamedPipe)
  1770. {
  1771. // try opening the pipe for reading?
  1772. return true;
  1773. }
  1774. return Exists();
  1775. }
  1776. // try opening and catch sharing violation?
  1777. /// <summary>
  1778. /// Tests to see if the file this <code>SmbFile</code> represents
  1779. /// exists and is not marked read-only.
  1780. /// </summary>
  1781. /// <remarks>
  1782. /// Tests to see if the file this <code>SmbFile</code> represents
  1783. /// exists and is not marked read-only. By default, resources are
  1784. /// considered to be read-only and therefore for <code>smb://</code>,
  1785. /// <code>smb://workgroup/</code>, and <code>smb://server/</code> resources
  1786. /// will be read-only.
  1787. /// </remarks>
  1788. /// <returns>
  1789. /// <code>true</code> if the resource exists is not marked
  1790. /// read-only
  1791. /// </returns>
  1792. /// <exception cref="SharpCifs.Smb.SmbException"></exception>
  1793. public virtual bool CanWrite()
  1794. {
  1795. if (GetType() == TypeNamedPipe)
  1796. {
  1797. // try opening the pipe for writing?
  1798. return true;
  1799. }
  1800. return Exists() && (_attributes & AttrReadonly) == 0;
  1801. }
  1802. /// <summary>Tests to see if the file this <code>SmbFile</code> represents is a directory.
  1803. /// </summary>
  1804. /// <remarks>Tests to see if the file this <code>SmbFile</code> represents is a directory.
  1805. /// </remarks>
  1806. /// <returns><code>true</code> if this <code>SmbFile</code> is a directory</returns>
  1807. /// <exception cref="SharpCifs.Smb.SmbException"></exception>
  1808. public virtual bool IsDirectory()
  1809. {
  1810. if (GetUncPath0().Length == 1)
  1811. {
  1812. return true;
  1813. }
  1814. if (!Exists())
  1815. {
  1816. return false;
  1817. }
  1818. return (_attributes & AttrDirectory) == AttrDirectory;
  1819. }
  1820. /// <summary>Tests to see if the file this <code>SmbFile</code> represents is not a directory.
  1821. /// </summary>
  1822. /// <remarks>Tests to see if the file this <code>SmbFile</code> represents is not a directory.
  1823. /// </remarks>
  1824. /// <returns><code>true</code> if this <code>SmbFile</code> is not a directory</returns>
  1825. /// <exception cref="SharpCifs.Smb.SmbException"></exception>
  1826. public virtual bool IsFile()
  1827. {
  1828. if (GetUncPath0().Length == 1)
  1829. {
  1830. return false;
  1831. }
  1832. Exists();
  1833. return (_attributes & AttrDirectory) == 0;
  1834. }
  1835. /// <summary>
  1836. /// Tests to see if the file this SmbFile represents is marked as
  1837. /// hidden.
  1838. /// </summary>
  1839. /// <remarks>
  1840. /// Tests to see if the file this SmbFile represents is marked as
  1841. /// hidden. This method will also return true for shares with names that
  1842. /// end with '$' such as <code>IPC$</code> or <code>C$</code>.
  1843. /// </remarks>
  1844. /// <returns><code>true</code> if the <code>SmbFile</code> is marked as being hidden</returns>
  1845. /// <exception cref="SharpCifs.Smb.SmbException"></exception>
  1846. public virtual bool IsHidden()
  1847. {
  1848. if (_share == null)
  1849. {
  1850. return false;
  1851. }
  1852. if (GetUncPath0().Length == 1)
  1853. {
  1854. if (_share.EndsWith("$"))
  1855. {
  1856. return true;
  1857. }
  1858. return false;
  1859. }
  1860. Exists();
  1861. return (_attributes & AttrHidden) == AttrHidden;
  1862. }
  1863. /// <summary>
  1864. /// If the path of this <code>SmbFile</code> falls within a DFS volume,
  1865. /// this method will return the referral path to which it maps.
  1866. /// </summary>
  1867. /// <remarks>
  1868. /// If the path of this <code>SmbFile</code> falls within a DFS volume,
  1869. /// this method will return the referral path to which it maps. Otherwise
  1870. /// <code>null</code> is returned.
  1871. /// </remarks>
  1872. /// <exception cref="SharpCifs.Smb.SmbException"></exception>
  1873. public virtual string GetDfsPath()
  1874. {
  1875. ResolveDfs(null);
  1876. if (_dfsReferral == null)
  1877. {
  1878. return null;
  1879. }
  1880. string path = "smb:/" + _dfsReferral.Server + "/" + _dfsReferral.Share + Unc;
  1881. path = path.Replace('\\', '/');
  1882. if (IsDirectory())
  1883. {
  1884. path += '/';
  1885. }
  1886. return path;
  1887. }
  1888. /// <summary>Retrieve the time this <code>SmbFile</code> was created.</summary>
  1889. /// <remarks>
  1890. /// Retrieve the time this <code>SmbFile</code> was created. The value
  1891. /// returned is suitable for constructing a
  1892. /// <see cref="System.DateTime">System.DateTime</see>
  1893. /// object
  1894. /// (i.e. seconds since Epoch 1970). Times should be the same as those
  1895. /// reported using the properties dialog of the Windows Explorer program.
  1896. /// For Win95/98/Me this is actually the last write time. It is currently
  1897. /// not possible to retrieve the create time from files on these systems.
  1898. /// </remarks>
  1899. /// <returns>
  1900. /// The number of milliseconds since the 00:00:00 GMT, January 1,
  1901. /// 1970 as a <code>long</code> value
  1902. /// </returns>
  1903. /// <exception cref="SharpCifs.Smb.SmbException"></exception>
  1904. public virtual long CreateTime()
  1905. {
  1906. if (GetUncPath0().Length > 1)
  1907. {
  1908. Exists();
  1909. return _createTime;
  1910. }
  1911. return 0L;
  1912. }
  1913. /// <summary>
  1914. /// Retrieve the last time the file represented by this
  1915. /// <code>SmbFile</code> was modified.
  1916. /// </summary>
  1917. /// <remarks>
  1918. /// Retrieve the last time the file represented by this
  1919. /// <code>SmbFile</code> was modified. The value returned is suitable for
  1920. /// constructing a
  1921. /// <see cref="System.DateTime">System.DateTime</see>
  1922. /// object (i.e. seconds since Epoch
  1923. /// 1970). Times should be the same as those reported using the properties
  1924. /// dialog of the Windows Explorer program.
  1925. /// </remarks>
  1926. /// <returns>
  1927. /// The number of milliseconds since the 00:00:00 GMT, January 1,
  1928. /// 1970 as a <code>long</code> value
  1929. /// </returns>
  1930. /// <exception cref="SharpCifs.Smb.SmbException"></exception>
  1931. public virtual long LastModified()
  1932. {
  1933. if (GetUncPath0().Length > 1)
  1934. {
  1935. Exists();
  1936. return _lastModified;
  1937. }
  1938. return 0L;
  1939. }
  1940. /// <summary>List the contents of this SMB resource.</summary>
  1941. /// <remarks>
  1942. /// List the contents of this SMB resource. The list returned by this
  1943. /// method will be;
  1944. /// <ul>
  1945. /// <li> files and directories contained within this resource if the
  1946. /// resource is a normal disk file directory,
  1947. /// <li> all available NetBIOS workgroups or domains if this resource is
  1948. /// the top level URL <code>smb://</code>,
  1949. /// <li> all servers registered as members of a NetBIOS workgroup if this
  1950. /// resource refers to a workgroup in a <code>smb://workgroup/</code> URL,
  1951. /// <li> all browseable shares of a server including printers, IPC
  1952. /// services, or disk volumes if this resource is a server URL in the form
  1953. /// <code>smb://server/</code>,
  1954. /// <li> or <code>null</code> if the resource cannot be resolved.
  1955. /// </ul>
  1956. /// </remarks>
  1957. /// <returns>
  1958. /// A <code>String[]</code> array of files and directories,
  1959. /// workgroups, servers, or shares depending on the context of the
  1960. /// resource URL
  1961. /// </returns>
  1962. /// <exception cref="SmbException"></exception>
  1963. public virtual string[] List()
  1964. {
  1965. return List("*", AttrDirectory | AttrHidden | AttrSystem, null, null);
  1966. }
  1967. /// <summary>List the contents of this SMB resource.</summary>
  1968. /// <remarks>
  1969. /// List the contents of this SMB resource. The list returned will be
  1970. /// identical to the list returned by the parameterless <code>list()</code>
  1971. /// method minus filenames filtered by the specified filter.
  1972. /// </remarks>
  1973. /// <param name="filter">a filename filter to exclude filenames from the results</param>
  1974. /// <exception cref="SmbException"># @return An array of filenames</exception>
  1975. /// <exception cref="SharpCifs.Smb.SmbException"></exception>
  1976. public virtual string[] List(ISmbFilenameFilter filter)
  1977. {
  1978. return List("*", AttrDirectory | AttrHidden | AttrSystem, filter, null);
  1979. }
  1980. /// <summary>
  1981. /// List the contents of this SMB resource as an array of
  1982. /// <code>SmbFile</code> objects.
  1983. /// </summary>
  1984. /// <remarks>
  1985. /// List the contents of this SMB resource as an array of
  1986. /// <code>SmbFile</code> objects. This method is much more efficient than
  1987. /// the regular <code>list</code> method when querying attributes of each
  1988. /// file in the result set.
  1989. /// <p>
  1990. /// The list of <code>SmbFile</code>s returned by this method will be;
  1991. /// <ul>
  1992. /// <li> files and directories contained within this resource if the
  1993. /// resource is a normal disk file directory,
  1994. /// <li> all available NetBIOS workgroups or domains if this resource is
  1995. /// the top level URL <code>smb://</code>,
  1996. /// <li> all servers registered as members of a NetBIOS workgroup if this
  1997. /// resource refers to a workgroup in a <code>smb://workgroup/</code> URL,
  1998. /// <li> all browseable shares of a server including printers, IPC
  1999. /// services, or disk volumes if this resource is a server URL in the form
  2000. /// <code>smb://server/</code>,
  2001. /// <li> or <code>null</code> if the resource cannot be resolved.
  2002. /// </ul>
  2003. /// </remarks>
  2004. /// <returns>
  2005. /// An array of <code>SmbFile</code> objects representing file
  2006. /// and directories, workgroups, servers, or shares depending on the context
  2007. /// of the resource URL
  2008. /// </returns>
  2009. /// <exception cref="SmbException"></exception>
  2010. public virtual SmbFile[] ListFiles()
  2011. {
  2012. return ListFiles("*", AttrDirectory | AttrHidden | AttrSystem, null, null);
  2013. }
  2014. /// <summary>
  2015. /// The CIFS protocol provides for DOS "wildcards" to be used as
  2016. /// a performance enhancement.
  2017. /// </summary>
  2018. /// <remarks>
  2019. /// The CIFS protocol provides for DOS "wildcards" to be used as
  2020. /// a performance enhancement. The client does not have to filter
  2021. /// the names and the server does not have to return all directory
  2022. /// entries.
  2023. /// <p>
  2024. /// The wildcard expression may consist of two special meta
  2025. /// characters in addition to the normal filename characters. The '*'
  2026. /// character matches any number of characters in part of a name. If
  2027. /// the expression begins with one or more '?'s then exactly that
  2028. /// many characters will be matched whereas if it ends with '?'s
  2029. /// it will match that many characters <i>or less</i>.
  2030. /// <p>
  2031. /// Wildcard expressions will not filter workgroup names or server names.
  2032. /// <blockquote><pre>
  2033. /// winnt&gt; ls c?o
  2034. /// clock.avi -rw-- 82944 Mon Oct 14 1996 1:38 AM
  2035. /// Cookies drw-- 0 Fri Nov 13 1998 9:42 PM
  2036. /// 2 items in 5ms
  2037. /// </pre></blockquote>
  2038. /// </remarks>
  2039. /// <param name="wildcard">a wildcard expression</param>
  2040. /// <exception cref="SmbException">SmbException</exception>
  2041. /// <returns>
  2042. /// An array of <code>SmbFile</code> objects representing file
  2043. /// and directories, workgroups, servers, or shares depending on the context
  2044. /// of the resource URL
  2045. /// </returns>
  2046. /// <exception cref="SmbException"></exception>
  2047. public virtual SmbFile[] ListFiles(string wildcard)
  2048. {
  2049. return ListFiles(wildcard,
  2050. AttrDirectory | AttrHidden | AttrSystem,
  2051. null,
  2052. null);
  2053. }
  2054. /// <summary>List the contents of this SMB resource.</summary>
  2055. /// <remarks>
  2056. /// List the contents of this SMB resource. The list returned will be
  2057. /// identical to the list returned by the parameterless <code>listFiles()</code>
  2058. /// method minus files filtered by the specified filename filter.
  2059. /// </remarks>
  2060. /// <param name="filter">a filter to exclude files from the results</param>
  2061. /// <returns>An array of <tt>SmbFile</tt> objects</returns>
  2062. /// <exception cref="SmbException">SmbException</exception>
  2063. /// <exception cref="SharpCifs.Smb.SmbException"></exception>
  2064. public virtual SmbFile[] ListFiles(ISmbFilenameFilter filter)
  2065. {
  2066. return ListFiles("*", AttrDirectory | AttrHidden | AttrSystem, filter, null);
  2067. }
  2068. /// <summary>List the contents of this SMB resource.</summary>
  2069. /// <remarks>
  2070. /// List the contents of this SMB resource. The list returned will be
  2071. /// identical to the list returned by the parameterless <code>listFiles()</code>
  2072. /// method minus filenames filtered by the specified filter.
  2073. /// </remarks>
  2074. /// <param name="filter">a file filter to exclude files from the results</param>
  2075. /// <returns>An array of <tt>SmbFile</tt> objects</returns>
  2076. /// <exception cref="SharpCifs.Smb.SmbException"></exception>
  2077. public virtual SmbFile[] ListFiles(ISmbFileFilter filter)
  2078. {
  2079. return ListFiles("*", AttrDirectory | AttrHidden | AttrSystem, null, filter);
  2080. }
  2081. /// <exception cref="SharpCifs.Smb.SmbException"></exception>
  2082. internal virtual string[] List(string wildcard,
  2083. int searchAttributes,
  2084. ISmbFilenameFilter fnf,
  2085. ISmbFileFilter ff)
  2086. {
  2087. List<object> list = new List<object>();
  2088. DoEnum(list, false, wildcard, searchAttributes, fnf, ff);
  2089. return Collections.ToArray<string>(list); //Collections.ToArray<string>(list);
  2090. }
  2091. /// <exception cref="SharpCifs.Smb.SmbException"></exception>
  2092. internal virtual SmbFile[] ListFiles(string wildcard,
  2093. int searchAttributes,
  2094. ISmbFilenameFilter fnf,
  2095. ISmbFileFilter ff)
  2096. {
  2097. List<object> list = new List<object>();
  2098. DoEnum(list, true, wildcard, searchAttributes, fnf, ff);
  2099. return Collections.ToArray<SmbFile>(list); //Collections.ToArray<SmbFile>(list);
  2100. }
  2101. /// <exception cref="SharpCifs.Smb.SmbException"></exception>
  2102. internal virtual void DoEnum(List<object> list,
  2103. bool files,
  2104. string wildcard,
  2105. int searchAttributes,
  2106. ISmbFilenameFilter fnf,
  2107. ISmbFileFilter ff)
  2108. {
  2109. if (ff != null && ff is DosFileFilter)
  2110. {
  2111. DosFileFilter dff = (DosFileFilter)ff;
  2112. if (dff.Wildcard != null)
  2113. {
  2114. wildcard = dff.Wildcard;
  2115. }
  2116. searchAttributes = dff.Attributes;
  2117. }
  2118. try
  2119. {
  2120. int hostlen = Url.GetHost() != null
  2121. ? Url.GetHost().Length
  2122. : 0;
  2123. if (hostlen == 0 || GetType() == TypeWorkgroup)
  2124. {
  2125. DoNetServerEnum(list, files, wildcard, searchAttributes, fnf, ff);
  2126. }
  2127. else
  2128. {
  2129. if (_share == null)
  2130. {
  2131. DoShareEnum(list, files, wildcard, searchAttributes, fnf, ff);
  2132. }
  2133. else
  2134. {
  2135. DoFindFirstNext(list, files, wildcard, searchAttributes, fnf, ff);
  2136. }
  2137. }
  2138. }
  2139. catch (UnknownHostException uhe)
  2140. {
  2141. throw new SmbException(Url.ToString(), uhe);
  2142. }
  2143. catch (UriFormatException mue)
  2144. {
  2145. throw new SmbException(Url.ToString(), mue);
  2146. }
  2147. }
  2148. private void RemoveCurrentAddress()
  2149. {
  2150. if (AddressIndex >= 1)
  2151. {
  2152. UniAddress[] aux = new UniAddress[Addresses.Length - 1];
  2153. Array.Copy(Addresses, 1, aux, 0, Addresses.Length - 1);
  2154. Addresses = aux;
  2155. AddressIndex--;
  2156. }
  2157. }
  2158. /// <exception cref="SharpCifs.Smb.SmbException"></exception>
  2159. /// <exception cref="UnknownHostException"></exception>
  2160. /// <exception cref="System.UriFormatException"></exception>
  2161. internal virtual void DoShareEnum(List<object> list,
  2162. bool files,
  2163. string wildcard,
  2164. int searchAttributes,
  2165. ISmbFilenameFilter fnf,
  2166. ISmbFileFilter ff)
  2167. {
  2168. string p = Url.AbsolutePath;
  2169. IOException last = null;
  2170. IFileEntry[] entries;
  2171. UniAddress addr;
  2172. IFileEntry e;
  2173. Hashtable map;
  2174. if (p.LastIndexOf('/') != (p.Length - 1))
  2175. {
  2176. throw new SmbException(Url + " directory must end with '/'");
  2177. }
  2178. if (GetType() != TypeServer)
  2179. {
  2180. throw new SmbException("The requested list operations is invalid: " + Url);
  2181. }
  2182. map = new Hashtable();
  2183. if (_enableDfs && Dfs.IsTrustedDomain(GetServer(), Auth))
  2184. {
  2185. try
  2186. {
  2187. entries = DoDfsRootEnum();
  2188. for (int ei = 0; ei < entries.Length; ei++)
  2189. {
  2190. e = entries[ei];
  2191. if (map.ContainsKey(e) == false)
  2192. {
  2193. map.Put(e, e);
  2194. }
  2195. }
  2196. }
  2197. catch (IOException ioe)
  2198. {
  2199. if (Log.Level >= 4)
  2200. {
  2201. Runtime.PrintStackTrace(ioe, Log);
  2202. }
  2203. }
  2204. }
  2205. addr = GetFirstAddress();
  2206. while (addr != null)
  2207. {
  2208. try
  2209. {
  2210. last = null;
  2211. DoConnect();
  2212. try
  2213. {
  2214. entries = DoMsrpcShareEnum();
  2215. }
  2216. catch (IOException ioe)
  2217. {
  2218. if (Log.Level >= 3)
  2219. {
  2220. Runtime.PrintStackTrace(ioe, Log);
  2221. }
  2222. entries = DoNetShareEnum();
  2223. }
  2224. for (int ei = 0; ei < entries.Length; ei++)
  2225. {
  2226. e = entries[ei];
  2227. if (map.ContainsKey(e) == false)
  2228. {
  2229. map.Put(e, e);
  2230. }
  2231. }
  2232. break;
  2233. }
  2234. catch (IOException ioe)
  2235. {
  2236. if (Log.Level >= 3)
  2237. {
  2238. Runtime.PrintStackTrace(ioe, Log);
  2239. }
  2240. last = ioe;
  2241. if (!(ioe is SmbAuthException))
  2242. {
  2243. RemoveCurrentAddress();
  2244. addr = GetNextAddress();
  2245. }
  2246. else
  2247. {
  2248. break;
  2249. }
  2250. }
  2251. }
  2252. if (last != null && map.Count == 0)
  2253. {
  2254. if (last is SmbException == false)
  2255. {
  2256. throw new SmbException(Url.ToString(), last);
  2257. }
  2258. throw (SmbException)last;
  2259. }
  2260. //Iterator iter = map.Keys.Iterator();
  2261. //while (iter.HasNext())
  2262. foreach (var item in map.Keys)
  2263. {
  2264. e = (IFileEntry)item;
  2265. string name = e.GetName();
  2266. if (fnf != null && fnf.Accept(this, name) == false)
  2267. {
  2268. continue;
  2269. }
  2270. if (name.Length > 0)
  2271. {
  2272. // if !files we don't need to create SmbFiles here
  2273. SmbFile f = new SmbFile(this,
  2274. name,
  2275. e.GetType(),
  2276. AttrReadonly | AttrDirectory,
  2277. 0L,
  2278. 0L,
  2279. 0L);
  2280. if (ff != null && ff.Accept(f) == false)
  2281. {
  2282. continue;
  2283. }
  2284. if (files)
  2285. {
  2286. list.Add(f);
  2287. }
  2288. else
  2289. {
  2290. list.Add(name);
  2291. }
  2292. }
  2293. }
  2294. }
  2295. /// <exception cref="System.IO.IOException"></exception>
  2296. internal virtual IFileEntry[] DoDfsRootEnum()
  2297. {
  2298. MsrpcDfsRootEnum rpc;
  2299. DcerpcHandle handle = null;
  2300. IFileEntry[] entries;
  2301. handle = DcerpcHandle.GetHandle("ncacn_np:"
  2302. + GetAddress().GetHostAddress()
  2303. + "[\\PIPE\\netdfs]",
  2304. Auth);
  2305. try
  2306. {
  2307. rpc = new MsrpcDfsRootEnum(GetServer());
  2308. handle.Sendrecv(rpc);
  2309. if (rpc.Retval != 0)
  2310. {
  2311. throw new SmbException(rpc.Retval, true);
  2312. }
  2313. return rpc.GetEntries();
  2314. }
  2315. finally
  2316. {
  2317. try
  2318. {
  2319. handle.Close();
  2320. }
  2321. catch (IOException ioe)
  2322. {
  2323. if (Log.Level >= 4)
  2324. {
  2325. Runtime.PrintStackTrace(ioe, Log);
  2326. }
  2327. }
  2328. }
  2329. }
  2330. /// <exception cref="System.IO.IOException"></exception>
  2331. internal virtual IFileEntry[] DoMsrpcShareEnum()
  2332. {
  2333. MsrpcShareEnum rpc;
  2334. DcerpcHandle handle;
  2335. rpc = new MsrpcShareEnum(Url.GetHost());
  2336. handle = DcerpcHandle.GetHandle("ncacn_np:"
  2337. + GetAddress().GetHostAddress()
  2338. + "[\\PIPE\\srvsvc]",
  2339. Auth);
  2340. try
  2341. {
  2342. handle.Sendrecv(rpc);
  2343. if (rpc.Retval != 0)
  2344. {
  2345. throw new SmbException(rpc.Retval, true);
  2346. }
  2347. return rpc.GetEntries();
  2348. }
  2349. finally
  2350. {
  2351. try
  2352. {
  2353. handle.Close();
  2354. }
  2355. catch (IOException ioe)
  2356. {
  2357. if (Log.Level >= 4)
  2358. {
  2359. Runtime.PrintStackTrace(ioe, Log);
  2360. }
  2361. }
  2362. }
  2363. }
  2364. /// <exception cref="SharpCifs.Smb.SmbException"></exception>
  2365. internal virtual IFileEntry[] DoNetShareEnum()
  2366. {
  2367. SmbComTransaction req = new NetShareEnum();
  2368. SmbComTransactionResponse resp = new NetShareEnumResponse();
  2369. Send(req, resp);
  2370. if (resp.Status != WinError.ErrorSuccess)
  2371. {
  2372. throw new SmbException(resp.Status, true);
  2373. }
  2374. return resp.Results;
  2375. }
  2376. /// <exception cref="SharpCifs.Smb.SmbException"></exception>
  2377. /// <exception cref="UnknownHostException"></exception>
  2378. /// <exception cref="System.UriFormatException"></exception>
  2379. internal virtual void DoNetServerEnum(List<object> list,
  2380. bool files,
  2381. string wildcard,
  2382. int searchAttributes,
  2383. ISmbFilenameFilter fnf,
  2384. ISmbFileFilter ff)
  2385. {
  2386. int listType = Url.GetHost().Length == 0
  2387. ? 0
  2388. : GetType();
  2389. SmbComTransaction req;
  2390. SmbComTransactionResponse resp;
  2391. if (listType == 0)
  2392. {
  2393. Connect0();
  2394. req = new NetServerEnum2(Tree.Session.transport.Server.OemDomainName,
  2395. NetServerEnum2.SvTypeDomainEnum);
  2396. resp = new NetServerEnum2Response();
  2397. }
  2398. else
  2399. {
  2400. if (listType == TypeWorkgroup)
  2401. {
  2402. req = new NetServerEnum2(Url.GetHost(), NetServerEnum2.SvTypeAll);
  2403. resp = new NetServerEnum2Response();
  2404. }
  2405. else
  2406. {
  2407. throw new SmbException("The requested list operations is invalid: " + Url);
  2408. }
  2409. }
  2410. bool more;
  2411. do
  2412. {
  2413. int n;
  2414. Send(req, resp);
  2415. if (resp.Status != WinError.ErrorSuccess && resp.Status != WinError.ErrorMoreData)
  2416. {
  2417. throw new SmbException(resp.Status, true);
  2418. }
  2419. more = resp.Status == WinError.ErrorMoreData;
  2420. n = more ? resp.NumEntries - 1 : resp.NumEntries;
  2421. for (int i = 0; i < n; i++)
  2422. {
  2423. IFileEntry e = resp.Results[i];
  2424. string name = e.GetName();
  2425. if (fnf != null && fnf.Accept(this, name) == false)
  2426. {
  2427. continue;
  2428. }
  2429. if (name.Length > 0)
  2430. {
  2431. // if !files we don't need to create SmbFiles here
  2432. SmbFile f = new SmbFile(this,
  2433. name,
  2434. e.GetType(),
  2435. AttrReadonly | AttrDirectory,
  2436. 0L,
  2437. 0L,
  2438. 0L);
  2439. if (ff != null && ff.Accept(f) == false)
  2440. {
  2441. continue;
  2442. }
  2443. if (files)
  2444. {
  2445. list.Add(f);
  2446. }
  2447. else
  2448. {
  2449. list.Add(name);
  2450. }
  2451. }
  2452. }
  2453. if (GetType() != TypeWorkgroup)
  2454. {
  2455. break;
  2456. }
  2457. req.SubCommand = unchecked(SmbComTransaction.NetServerEnum3);
  2458. req.Reset(0, ((NetServerEnum2Response)resp).LastName);
  2459. resp.Reset();
  2460. }
  2461. while (more);
  2462. }
  2463. /// <exception cref="SharpCifs.Smb.SmbException"></exception>
  2464. /// <exception cref="UnknownHostException"></exception>
  2465. /// <exception cref="System.UriFormatException"></exception>
  2466. internal virtual void DoFindFirstNext(List<object> list,
  2467. bool files,
  2468. string wildcard,
  2469. int searchAttributes,
  2470. ISmbFilenameFilter fnf,
  2471. ISmbFileFilter ff)
  2472. {
  2473. SmbComTransaction req;
  2474. Trans2FindFirst2Response resp;
  2475. int sid;
  2476. string path = GetUncPath0();
  2477. string p = Url.AbsolutePath;
  2478. if (p.LastIndexOf('/') != (p.Length - 1))
  2479. {
  2480. throw new SmbException(Url + " directory must end with '/'");
  2481. }
  2482. req = new Trans2FindFirst2(path, wildcard, searchAttributes);
  2483. resp = new Trans2FindFirst2Response();
  2484. if (Log.Level >= 3)
  2485. {
  2486. Log.WriteLine("doFindFirstNext: " + req.Path);
  2487. }
  2488. Send(req, resp);
  2489. sid = resp.Sid;
  2490. req = new Trans2FindNext2(sid, resp.ResumeKey, resp.LastName);
  2491. resp.SubCommand = SmbComTransaction.Trans2FindNext2;
  2492. for (;;)
  2493. {
  2494. for (int i = 0; i < resp.NumEntries; i++)
  2495. {
  2496. IFileEntry e = resp.Results[i];
  2497. string name = e.GetName();
  2498. if (name.Length < 3)
  2499. {
  2500. int h = name.GetHashCode();
  2501. if (h == HashDot || h == HashDotDot)
  2502. {
  2503. if (name.Equals(".") || name.Equals(".."))
  2504. {
  2505. continue;
  2506. }
  2507. }
  2508. }
  2509. if (fnf != null && fnf.Accept(this, name) == false)
  2510. {
  2511. continue;
  2512. }
  2513. if (name.Length > 0)
  2514. {
  2515. SmbFile f = new SmbFile(this,
  2516. name,
  2517. TypeFilesystem,
  2518. e.GetAttributes(),
  2519. e.CreateTime(),
  2520. e.LastModified(),
  2521. e.Length());
  2522. if (ff != null && ff.Accept(f) == false)
  2523. {
  2524. continue;
  2525. }
  2526. if (files)
  2527. {
  2528. list.Add(f);
  2529. }
  2530. else
  2531. {
  2532. list.Add(name);
  2533. }
  2534. }
  2535. }
  2536. if (resp.IsEndOfSearch || resp.NumEntries == 0)
  2537. {
  2538. break;
  2539. }
  2540. req.Reset(resp.ResumeKey, resp.LastName);
  2541. resp.Reset();
  2542. Send(req, resp);
  2543. }
  2544. try
  2545. {
  2546. Send(new SmbComFindClose2(sid), Blank_resp());
  2547. }
  2548. catch (SmbException se)
  2549. {
  2550. if (Log.Level >= 4)
  2551. {
  2552. Runtime.PrintStackTrace(se, Log);
  2553. }
  2554. }
  2555. }
  2556. /// <summary>
  2557. /// Changes the name of the file this <code>SmbFile</code> represents to the name
  2558. /// designated by the <code>SmbFile</code> argument.
  2559. /// </summary>
  2560. /// <remarks>
  2561. /// Changes the name of the file this <code>SmbFile</code> represents to the name
  2562. /// designated by the <code>SmbFile</code> argument.
  2563. /// <p/>
  2564. /// <i>Remember: <code>SmbFile</code>s are immutible and therefore
  2565. /// the path associated with this <code>SmbFile</code> object will not
  2566. /// change). To access the renamed file it is necessary to construct a
  2567. /// new <tt>SmbFile</tt></i>.
  2568. /// </remarks>
  2569. /// <param name="dest">An <code>SmbFile</code> that represents the new pathname</param>
  2570. /// <exception cref="System.ArgumentNullException">If the <code>dest</code> argument is <code>null</code>
  2571. /// </exception>
  2572. /// <exception cref="SharpCifs.Smb.SmbException"></exception>
  2573. public virtual void RenameTo(SmbFile dest)
  2574. {
  2575. if (GetUncPath0().Length == 1 || dest.GetUncPath0().Length == 1)
  2576. {
  2577. throw new SmbException("Invalid operation for workgroups, servers, or shares");
  2578. }
  2579. ResolveDfs(null);
  2580. dest.ResolveDfs(null);
  2581. if (!Tree.Equals(dest.Tree))
  2582. {
  2583. throw new SmbException("Invalid operation for workgroups, servers, or shares");
  2584. }
  2585. if (Log.Level >= 3)
  2586. {
  2587. Log.WriteLine("renameTo: " + Unc + " -> " + dest.Unc);
  2588. }
  2589. _attrExpiration = _sizeExpiration = 0;
  2590. dest._attrExpiration = 0;
  2591. Send(new SmbComRename(Unc, dest.Unc), Blank_resp());
  2592. }
  2593. internal class WriterThread : Thread
  2594. {
  2595. internal byte[] B;
  2596. internal int N;
  2597. internal long Off;
  2598. internal bool Ready;
  2599. internal SmbFile Dest;
  2600. internal SmbException E;
  2601. internal bool UseNtSmbs;
  2602. internal SmbComWriteAndX Reqx;
  2603. internal SmbComWrite Req;
  2604. internal ServerMessageBlock Resp;
  2605. /// <exception cref="SharpCifs.Smb.SmbException"></exception>
  2606. public WriterThread(SmbFile enclosing)
  2607. : base("JCIFS-WriterThread")
  2608. {
  2609. this._enclosing = enclosing;
  2610. UseNtSmbs = this._enclosing.Tree
  2611. .Session
  2612. .transport
  2613. .HasCapability(SmbConstants.CapNtSmbs);
  2614. if (UseNtSmbs)
  2615. {
  2616. Reqx = new SmbComWriteAndX();
  2617. Resp = new SmbComWriteAndXResponse();
  2618. }
  2619. else
  2620. {
  2621. Req = new SmbComWrite();
  2622. Resp = new SmbComWriteResponse();
  2623. }
  2624. Ready = false;
  2625. }
  2626. internal virtual void Write(byte[] b, int n, SmbFile dest, long off)
  2627. {
  2628. lock (this)
  2629. {
  2630. this.B = b;
  2631. this.N = n;
  2632. this.Dest = dest;
  2633. this.Off = off;
  2634. Ready = false;
  2635. Runtime.Notify(this);
  2636. }
  2637. }
  2638. public override void Run()
  2639. {
  2640. lock (this)
  2641. {
  2642. try
  2643. {
  2644. for (;;)
  2645. {
  2646. Runtime.Notify(this);
  2647. Ready = true;
  2648. while (Ready)
  2649. {
  2650. Runtime.Wait(this);
  2651. }
  2652. if (N == -1)
  2653. {
  2654. return;
  2655. }
  2656. if (UseNtSmbs)
  2657. {
  2658. Reqx.SetParam(Dest.Fid, Off, N, B, 0, N);
  2659. Dest.Send(Reqx, Resp);
  2660. }
  2661. else
  2662. {
  2663. Req.SetParam(Dest.Fid, Off, N, B, 0, N);
  2664. Dest.Send(Req, Resp);
  2665. }
  2666. }
  2667. }
  2668. catch (SmbException e)
  2669. {
  2670. this.E = e;
  2671. }
  2672. catch (Exception x)
  2673. {
  2674. E = new SmbException("WriterThread", x);
  2675. }
  2676. Runtime.Notify(this);
  2677. }
  2678. }
  2679. private readonly SmbFile _enclosing;
  2680. }
  2681. /// <exception cref="SharpCifs.Smb.SmbException"></exception>
  2682. internal virtual void CopyTo0(SmbFile dest,
  2683. byte[][] b,
  2684. int bsize,
  2685. WriterThread w,
  2686. SmbComReadAndX req,
  2687. SmbComReadAndXResponse resp)
  2688. {
  2689. int i;
  2690. if (_attrExpiration < Runtime.CurrentTimeMillis())
  2691. {
  2692. _attributes = AttrReadonly | AttrDirectory;
  2693. _createTime = 0L;
  2694. _lastModified = 0L;
  2695. _isExists = false;
  2696. IInfo info = QueryPath(GetUncPath0(),
  2697. Trans2QueryPathInformationResponse.SMB_QUERY_FILE_BASIC_INFO);
  2698. _attributes = info.GetAttributes();
  2699. _createTime = info.GetCreateTime();
  2700. _lastModified = info.GetLastWriteTime();
  2701. _isExists = true;
  2702. _attrExpiration = Runtime.CurrentTimeMillis() + AttrExpirationPeriod;
  2703. }
  2704. if (IsDirectory())
  2705. {
  2706. SmbFile[] files;
  2707. SmbFile ndest;
  2708. string path = dest.GetUncPath0();
  2709. if (path.Length > 1)
  2710. {
  2711. try
  2712. {
  2713. dest.Mkdir();
  2714. dest.SetPathInformation(_attributes, _createTime, _lastModified);
  2715. }
  2716. catch (SmbException se)
  2717. {
  2718. if (se.GetNtStatus() != NtStatus.NtStatusAccessDenied
  2719. && se.GetNtStatus() != NtStatus.NtStatusObjectNameCollision)
  2720. {
  2721. throw;
  2722. }
  2723. }
  2724. }
  2725. files = ListFiles("*", AttrDirectory | AttrHidden | AttrSystem, null, null);
  2726. try
  2727. {
  2728. for (i = 0; i < files.Length; i++)
  2729. {
  2730. ndest = new SmbFile(dest,
  2731. files[i].GetName(),
  2732. files[i].Type,
  2733. files[i]._attributes,
  2734. files[i]._createTime,
  2735. files[i]._lastModified,
  2736. files[i]._size);
  2737. files[i].CopyTo0(ndest, b, bsize, w, req, resp);
  2738. }
  2739. }
  2740. catch (UnknownHostException uhe)
  2741. {
  2742. throw new SmbException(Url.ToString(), uhe);
  2743. }
  2744. catch (UriFormatException mue)
  2745. {
  2746. throw new SmbException(Url.ToString(), mue);
  2747. }
  2748. }
  2749. else
  2750. {
  2751. long off;
  2752. try
  2753. {
  2754. Open(ORdonly, 0, AttrNormal, 0);
  2755. try
  2756. {
  2757. dest.Open(OCreat | OWronly | OTrunc,
  2758. SmbConstants.FileWriteData | SmbConstants.FileWriteAttributes,
  2759. _attributes,
  2760. 0);
  2761. }
  2762. catch (SmbAuthException sae)
  2763. {
  2764. if ((dest._attributes & AttrReadonly) != 0)
  2765. {
  2766. dest.SetPathInformation(dest._attributes & ~AttrReadonly, 0L, 0L);
  2767. dest.Open(OCreat | OWronly | OTrunc,
  2768. SmbConstants.FileWriteData | SmbConstants.FileWriteAttributes,
  2769. _attributes,
  2770. 0);
  2771. }
  2772. else
  2773. {
  2774. throw;
  2775. }
  2776. }
  2777. i = 0;
  2778. off = 0L;
  2779. for (;;)
  2780. {
  2781. req.SetParam(Fid, off, bsize);
  2782. resp.SetParam(b[i], 0);
  2783. Send(req, resp);
  2784. lock (w)
  2785. {
  2786. if (w.E != null)
  2787. {
  2788. throw w.E;
  2789. }
  2790. while (!w.Ready)
  2791. {
  2792. try
  2793. {
  2794. Runtime.Wait(w);
  2795. }
  2796. catch (Exception ie)
  2797. {
  2798. throw new SmbException(dest.Url.ToString(), ie);
  2799. }
  2800. }
  2801. if (w.E != null)
  2802. {
  2803. throw w.E;
  2804. }
  2805. if (resp.DataLength <= 0)
  2806. {
  2807. break;
  2808. }
  2809. w.Write(b[i], resp.DataLength, dest, off);
  2810. }
  2811. i = i == 1 ? 0 : 1;
  2812. off += resp.DataLength;
  2813. }
  2814. dest.Send(new Trans2SetFileInformation(dest.Fid,
  2815. _attributes,
  2816. _createTime,
  2817. _lastModified),
  2818. new Trans2SetFileInformationResponse());
  2819. dest.Close(0L);
  2820. }
  2821. catch (SmbException se)
  2822. {
  2823. if (IgnoreCopyToException == false)
  2824. {
  2825. throw new SmbException("Failed to copy file from "
  2826. + "[" + ToString() + "] to [" + dest + "]", se);
  2827. }
  2828. if (Log.Level > 1)
  2829. {
  2830. Runtime.PrintStackTrace(se, Log);
  2831. }
  2832. }
  2833. finally
  2834. {
  2835. Close();
  2836. }
  2837. }
  2838. }
  2839. /// <summary>
  2840. /// This method will copy the file or directory represented by this
  2841. /// <tt>SmbFile</tt> and it's sub-contents to the location specified by the
  2842. /// <tt>dest</tt> parameter.
  2843. /// </summary>
  2844. /// <remarks>
  2845. /// This method will copy the file or directory represented by this
  2846. /// <tt>SmbFile</tt> and it's sub-contents to the location specified by the
  2847. /// <tt>dest</tt> parameter. This file and the destination file do not
  2848. /// need to be on the same host. This operation does not copy extended
  2849. /// file attibutes such as ACLs but it does copy regular attributes as
  2850. /// well as create and last write times. This method is almost twice as
  2851. /// efficient as manually copying as it employs an additional write
  2852. /// thread to read and write data concurrently.
  2853. /// <p/>
  2854. /// It is not possible (nor meaningful) to copy entire workgroups or
  2855. /// servers.
  2856. /// </remarks>
  2857. /// <param name="dest">the destination file or directory</param>
  2858. /// <exception cref="SmbException">SmbException</exception>
  2859. /// <exception cref="SharpCifs.Smb.SmbException"></exception>
  2860. public virtual void CopyTo(SmbFile dest)
  2861. {
  2862. SmbComReadAndX req;
  2863. SmbComReadAndXResponse resp;
  2864. WriterThread w;
  2865. int bsize;
  2866. byte[][] b;
  2867. if (_share == null || dest._share == null)
  2868. {
  2869. throw new SmbException("Invalid operation for workgroups or servers");
  2870. }
  2871. req = new SmbComReadAndX();
  2872. resp = new SmbComReadAndXResponse();
  2873. Connect0();
  2874. dest.Connect0();
  2875. ResolveDfs(null);
  2876. try
  2877. {
  2878. if (GetAddress().Equals(dest.GetAddress())
  2879. && _canon.RegionMatches(true, 0, dest._canon, 0, Math.Min(_canon.Length, dest._canon.Length)))
  2880. {
  2881. throw new SmbException("Source and destination paths overlap.");
  2882. }
  2883. }
  2884. catch (UnknownHostException)
  2885. {
  2886. }
  2887. w = new WriterThread(this);
  2888. w.SetDaemon(true);
  2889. w.Start(true);
  2890. SmbTransport t1 = Tree.Session.transport;
  2891. SmbTransport t2 = dest.Tree.Session.transport;
  2892. if (t1.SndBufSize < t2.SndBufSize)
  2893. {
  2894. t2.SndBufSize = t1.SndBufSize;
  2895. }
  2896. else
  2897. {
  2898. t1.SndBufSize = t2.SndBufSize;
  2899. }
  2900. bsize = Math.Min(t1.RcvBufSize - 70, t1.SndBufSize - 70);
  2901. b = new[] { new byte[bsize], new byte[bsize] };
  2902. try
  2903. {
  2904. CopyTo0(dest, b, bsize, w, req, resp);
  2905. }
  2906. finally
  2907. {
  2908. w.Write(null, -1, null, 0);
  2909. }
  2910. }
  2911. /// <summary>
  2912. /// This method will delete the file or directory specified by this
  2913. /// <code>SmbFile</code>.
  2914. /// </summary>
  2915. /// <remarks>
  2916. /// This method will delete the file or directory specified by this
  2917. /// <code>SmbFile</code>. If the target is a directory, the contents of
  2918. /// the directory will be deleted as well. If a file within the directory or
  2919. /// it's sub-directories is marked read-only, the read-only status will
  2920. /// be removed and the file will be deleted.
  2921. /// </remarks>
  2922. /// <exception cref="SmbException">SmbException</exception>
  2923. /// <exception cref="SharpCifs.Smb.SmbException"></exception>
  2924. public virtual void Delete()
  2925. {
  2926. Exists();
  2927. GetUncPath0();
  2928. Delete(Unc);
  2929. }
  2930. /// <exception cref="SharpCifs.Smb.SmbException"></exception>
  2931. internal virtual void Delete(string fileName)
  2932. {
  2933. if (GetUncPath0().Length == 1)
  2934. {
  2935. throw new SmbException("Invalid operation for workgroups, servers, or shares");
  2936. }
  2937. if (Runtime.CurrentTimeMillis() > _attrExpiration)
  2938. {
  2939. _attributes = AttrReadonly | AttrDirectory;
  2940. _createTime = 0L;
  2941. _lastModified = 0L;
  2942. _isExists = false;
  2943. IInfo info = QueryPath(GetUncPath0(),
  2944. Trans2QueryPathInformationResponse.SMB_QUERY_FILE_BASIC_INFO);
  2945. _attributes = info.GetAttributes();
  2946. _createTime = info.GetCreateTime();
  2947. _lastModified = info.GetLastWriteTime();
  2948. _attrExpiration = Runtime.CurrentTimeMillis() + AttrExpirationPeriod;
  2949. _isExists = true;
  2950. }
  2951. if ((_attributes & AttrReadonly) != 0)
  2952. {
  2953. SetReadWrite();
  2954. }
  2955. if (Log.Level >= 3)
  2956. {
  2957. Log.WriteLine("delete: " + fileName);
  2958. }
  2959. if ((_attributes & AttrDirectory) != 0)
  2960. {
  2961. try
  2962. {
  2963. SmbFile[] l = ListFiles("*", AttrDirectory | AttrHidden | AttrSystem, null, null);
  2964. for (int i = 0; i < l.Length; i++)
  2965. {
  2966. l[i].Delete();
  2967. }
  2968. }
  2969. catch (SmbException se)
  2970. {
  2971. if (se.GetNtStatus() != NtStatus.NtStatusNoSuchFile)
  2972. {
  2973. throw;
  2974. }
  2975. }
  2976. Send(new SmbComDeleteDirectory(fileName), Blank_resp());
  2977. }
  2978. else
  2979. {
  2980. Send(new SmbComDelete(fileName), Blank_resp());
  2981. }
  2982. _attrExpiration = _sizeExpiration = 0;
  2983. }
  2984. /// <summary>Returns the length of this <tt>SmbFile</tt> in bytes.</summary>
  2985. /// <remarks>
  2986. /// Returns the length of this <tt>SmbFile</tt> in bytes. If this object
  2987. /// is a <tt>TYPE_SHARE</tt> the total capacity of the disk shared in
  2988. /// bytes is returned. If this object is a directory or a type other than
  2989. /// <tt>TYPE_SHARE</tt>, 0L is returned.
  2990. /// </remarks>
  2991. /// <returns>
  2992. /// The length of the file in bytes or 0 if this
  2993. /// <code>SmbFile</code> is not a file.
  2994. /// </returns>
  2995. /// <exception cref="SmbException">SmbException</exception>
  2996. /// <exception cref="SharpCifs.Smb.SmbException"></exception>
  2997. public virtual long Length()
  2998. {
  2999. if (_sizeExpiration > Runtime.CurrentTimeMillis())
  3000. {
  3001. return _size;
  3002. }
  3003. if (GetType() == TypeShare)
  3004. {
  3005. Trans2QueryFsInformationResponse response;
  3006. int level = Trans2QueryFsInformationResponse.SMB_INFO_ALLOCATION;
  3007. response = new Trans2QueryFsInformationResponse(level);
  3008. Send(new Trans2QueryFsInformation(level), response);
  3009. _size = response.Info.GetCapacity();
  3010. }
  3011. else
  3012. {
  3013. if (GetUncPath0().Length > 1 && Type != TypeNamedPipe)
  3014. {
  3015. IInfo info = QueryPath(GetUncPath0(),
  3016. Trans2QueryPathInformationResponse.SMB_QUERY_FILE_STANDARD_INFO);
  3017. _size = info.GetSize();
  3018. }
  3019. else
  3020. {
  3021. _size = 0L;
  3022. }
  3023. }
  3024. _sizeExpiration = Runtime.CurrentTimeMillis() + AttrExpirationPeriod;
  3025. return _size;
  3026. }
  3027. /// <summary>
  3028. /// This method returns the free disk space in bytes of the drive this share
  3029. /// represents or the drive on which the directory or file resides.
  3030. /// </summary>
  3031. /// <remarks>
  3032. /// This method returns the free disk space in bytes of the drive this share
  3033. /// represents or the drive on which the directory or file resides. Objects
  3034. /// other than <tt>TYPE_SHARE</tt> or <tt>TYPE_FILESYSTEM</tt> will result
  3035. /// in 0L being returned.
  3036. /// </remarks>
  3037. /// <returns>
  3038. /// the free disk space in bytes of the drive on which this file or
  3039. /// directory resides
  3040. /// </returns>
  3041. /// <exception cref="SharpCifs.Smb.SmbException"></exception>
  3042. public virtual long GetDiskFreeSpace()
  3043. {
  3044. if (GetType() == TypeShare || Type == TypeFilesystem)
  3045. {
  3046. int level = Trans2QueryFsInformationResponse.SmbFsFullSizeInformation;
  3047. try
  3048. {
  3049. return QueryFsInformation(level);
  3050. }
  3051. catch (SmbException ex)
  3052. {
  3053. switch (ex.GetNtStatus())
  3054. {
  3055. case NtStatus.NtStatusInvalidInfoClass:
  3056. case NtStatus.NtStatusUnsuccessful:
  3057. {
  3058. // NetApp Filer
  3059. // SMB_FS_FULL_SIZE_INFORMATION not supported by the server.
  3060. level = Trans2QueryFsInformationResponse.SMB_INFO_ALLOCATION;
  3061. return QueryFsInformation(level);
  3062. }
  3063. }
  3064. throw;
  3065. }
  3066. }
  3067. return 0L;
  3068. }
  3069. /// <exception cref="SharpCifs.Smb.SmbException"></exception>
  3070. private long QueryFsInformation(int level)
  3071. {
  3072. Trans2QueryFsInformationResponse response;
  3073. response = new Trans2QueryFsInformationResponse(level);
  3074. Send(new Trans2QueryFsInformation(level), response);
  3075. if (Type == TypeShare)
  3076. {
  3077. _size = response.Info.GetCapacity();
  3078. _sizeExpiration = Runtime.CurrentTimeMillis() + AttrExpirationPeriod;
  3079. }
  3080. return response.Info.GetFree();
  3081. }
  3082. /// <summary>
  3083. /// Creates a directory with the path specified by this
  3084. /// <code>SmbFile</code>.
  3085. /// </summary>
  3086. /// <remarks>
  3087. /// Creates a directory with the path specified by this
  3088. /// <code>SmbFile</code>. For this method to be successful, the target
  3089. /// must not already exist. This method will fail when
  3090. /// used with <code>smb://</code>, <code>smb://workgroup/</code>,
  3091. /// <code>smb://server/</code>, or <code>smb://server/share/</code> URLs
  3092. /// because workgroups, servers, and shares cannot be dynamically created
  3093. /// (although in the future it may be possible to create shares).
  3094. /// </remarks>
  3095. /// <exception cref="SmbException">SmbException</exception>
  3096. /// <exception cref="SharpCifs.Smb.SmbException"></exception>
  3097. public virtual void Mkdir()
  3098. {
  3099. string path = GetUncPath0();
  3100. if (path.Length == 1)
  3101. {
  3102. throw new SmbException("Invalid operation for workgroups, servers, or shares");
  3103. }
  3104. if (Log.Level >= 3)
  3105. {
  3106. Log.WriteLine("mkdir: " + path);
  3107. }
  3108. Send(new SmbComCreateDirectory(path), Blank_resp());
  3109. _attrExpiration = _sizeExpiration = 0;
  3110. }
  3111. /// <summary>
  3112. /// Creates a directory with the path specified by this <tt>SmbFile</tt>
  3113. /// and any parent directories that do not exist.
  3114. /// </summary>
  3115. /// <remarks>
  3116. /// Creates a directory with the path specified by this <tt>SmbFile</tt>
  3117. /// and any parent directories that do not exist. This method will fail
  3118. /// when used with <code>smb://</code>, <code>smb://workgroup/</code>,
  3119. /// <code>smb://server/</code>, or <code>smb://server/share/</code> URLs
  3120. /// because workgroups, servers, and shares cannot be dynamically created
  3121. /// (although in the future it may be possible to create shares).
  3122. /// </remarks>
  3123. /// <exception cref="SmbException">SmbException</exception>
  3124. /// <exception cref="SharpCifs.Smb.SmbException"></exception>
  3125. public virtual void Mkdirs()
  3126. {
  3127. SmbFile parent;
  3128. try
  3129. {
  3130. parent = new SmbFile(GetParent(), Auth);
  3131. }
  3132. catch (IOException)
  3133. {
  3134. return;
  3135. }
  3136. if (parent.Exists() == false)
  3137. {
  3138. parent.Mkdirs();
  3139. }
  3140. Mkdir();
  3141. }
  3142. /// <summary>Create a new file but fail if it already exists.</summary>
  3143. /// <remarks>
  3144. /// Create a new file but fail if it already exists. The check for
  3145. /// existance of the file and it's creation are an atomic operation with
  3146. /// respect to other filesystem activities.
  3147. /// </remarks>
  3148. /// <exception cref="SharpCifs.Smb.SmbException"></exception>
  3149. public virtual void CreateNewFile()
  3150. {
  3151. if (GetUncPath0().Length == 1)
  3152. {
  3153. throw new SmbException("Invalid operation for workgroups, servers, or shares");
  3154. }
  3155. Close(Open0(ORdwr | OCreat | OExcl, 0, AttrNormal, 0), 0L);
  3156. }
  3157. /// <exception cref="SharpCifs.Smb.SmbException"></exception>
  3158. internal virtual void SetPathInformation(int attrs, long ctime, long mtime)
  3159. {
  3160. int f;
  3161. int dir;
  3162. Exists();
  3163. dir = _attributes & AttrDirectory;
  3164. f = Open0(ORdonly,
  3165. SmbConstants.FileWriteAttributes,
  3166. dir,
  3167. dir != 0
  3168. ? 0x0001
  3169. : 0x0040);
  3170. Send(new Trans2SetFileInformation(f, attrs | dir, ctime, mtime),
  3171. new Trans2SetFileInformationResponse());
  3172. Close(f, 0L);
  3173. _attrExpiration = 0;
  3174. }
  3175. /// <summary>Set the create time of the file.</summary>
  3176. /// <remarks>
  3177. /// Set the create time of the file. The time is specified as milliseconds
  3178. /// from Jan 1, 1970 which is the same as that which is returned by the
  3179. /// <tt>createTime()</tt> method.
  3180. /// <p/>
  3181. /// This method does not apply to workgroups, servers, or shares.
  3182. /// </remarks>
  3183. /// <param name="time">the create time as milliseconds since Jan 1, 1970</param>
  3184. /// <exception cref="SharpCifs.Smb.SmbException"></exception>
  3185. public virtual void SetCreateTime(long time)
  3186. {
  3187. if (GetUncPath0().Length == 1)
  3188. {
  3189. throw new SmbException("Invalid operation for workgroups, servers, or shares");
  3190. }
  3191. SetPathInformation(0, time, 0L);
  3192. }
  3193. /// <summary>Set the last modified time of the file.</summary>
  3194. /// <remarks>
  3195. /// Set the last modified time of the file. The time is specified as milliseconds
  3196. /// from Jan 1, 1970 which is the same as that which is returned by the
  3197. /// <tt>lastModified()</tt>, <tt>getLastModified()</tt>, and <tt>getDate()</tt> methods.
  3198. /// <p/>
  3199. /// This method does not apply to workgroups, servers, or shares.
  3200. /// </remarks>
  3201. /// <param name="time">the last modified time as milliseconds since Jan 1, 1970</param>
  3202. /// <exception cref="SharpCifs.Smb.SmbException"></exception>
  3203. public virtual void SetLastModified(long time)
  3204. {
  3205. if (GetUncPath0().Length == 1)
  3206. {
  3207. throw new SmbException("Invalid operation for workgroups, servers, or shares");
  3208. }
  3209. SetPathInformation(0, 0L, time);
  3210. }
  3211. /// <summary>Return the attributes of this file.</summary>
  3212. /// <remarks>
  3213. /// Return the attributes of this file. Attributes are represented as a
  3214. /// bitset that must be masked with <tt>ATTR_*</tt> constants to determine
  3215. /// if they are set or unset. The value returned is suitable for use with
  3216. /// the <tt>setAttributes()</tt> method.
  3217. /// </remarks>
  3218. /// <returns>the <tt>ATTR_*</tt> attributes associated with this file</returns>
  3219. /// <exception cref="SmbException">SmbException</exception>
  3220. /// <exception cref="SharpCifs.Smb.SmbException"></exception>
  3221. public virtual int GetAttributes()
  3222. {
  3223. if (GetUncPath0().Length == 1)
  3224. {
  3225. return 0;
  3226. }
  3227. Exists();
  3228. return _attributes & AttrGetMask;
  3229. }
  3230. /// <summary>Set the attributes of this file.</summary>
  3231. /// <remarks>
  3232. /// Set the attributes of this file. Attributes are composed into a
  3233. /// bitset by bitwise ORing the <tt>ATTR_*</tt> constants. Setting the
  3234. /// value returned by <tt>getAttributes</tt> will result in both files
  3235. /// having the same attributes.
  3236. /// </remarks>
  3237. /// <exception cref="SmbException">SmbException</exception>
  3238. /// <exception cref="SharpCifs.Smb.SmbException"></exception>
  3239. public virtual void SetAttributes(int attrs)
  3240. {
  3241. if (GetUncPath0().Length == 1)
  3242. {
  3243. throw new SmbException("Invalid operation for workgroups, servers, or shares");
  3244. }
  3245. SetPathInformation(attrs & AttrSetMask, 0L, 0L);
  3246. }
  3247. /// <summary>Make this file read-only.</summary>
  3248. /// <remarks>
  3249. /// Make this file read-only. This is shorthand for <tt>setAttributes(
  3250. /// getAttributes() | ATTR_READ_ONLY )</tt>.
  3251. /// </remarks>
  3252. /// <exception cref="SmbException">SmbException</exception>
  3253. /// <exception cref="SharpCifs.Smb.SmbException"></exception>
  3254. public virtual void SetReadOnly()
  3255. {
  3256. SetAttributes(GetAttributes() | AttrReadonly);
  3257. }
  3258. /// <summary>Turn off the read-only attribute of this file.</summary>
  3259. /// <remarks>
  3260. /// Turn off the read-only attribute of this file. This is shorthand for
  3261. /// <tt>setAttributes( getAttributes() & ~ATTR_READONLY )</tt>.
  3262. /// </remarks>
  3263. /// <exception cref="SmbException">SmbException</exception>
  3264. /// <exception cref="SmbException"></exception>
  3265. public virtual void SetReadWrite()
  3266. {
  3267. SetAttributes(GetAttributes() & ~AttrReadonly);
  3268. }
  3269. /// <summary>
  3270. /// Returns a
  3271. /// <see cref="System.Uri">System.Uri</see>
  3272. /// for this <code>SmbFile</code>. The
  3273. /// <code>URL</code> may be used as any other <code>URL</code> might to
  3274. /// access an SMB resource. Currently only retrieving data and information
  3275. /// is supported (i.e. no <tt>doOutput</tt>).
  3276. /// </summary>
  3277. /// <returns>
  3278. /// A new <code>
  3279. /// <see cref="System.Uri">System.Uri</see>
  3280. /// </code> for this <code>SmbFile</code>
  3281. /// </returns>
  3282. /// <exception cref="System.UriFormatException">System.UriFormatException</exception>
  3283. [Obsolete(@"Use getURL() instead")]
  3284. public virtual Uri ToUrl()
  3285. {
  3286. return Url;
  3287. }
  3288. /// <summary>
  3289. /// Computes a hashCode for this file based on the URL string and IP
  3290. /// address if the server.
  3291. /// </summary>
  3292. /// <remarks>
  3293. /// Computes a hashCode for this file based on the URL string and IP
  3294. /// address if the server. The hashing function uses the hashcode of the
  3295. /// server address, the canonical representation of the URL, and does not
  3296. /// compare authentication information. In essance, two
  3297. /// <code>SmbFile</code> objects that refer to
  3298. /// the same file should generate the same hashcode provided it is possible
  3299. /// to make such a determination.
  3300. /// </remarks>
  3301. /// <returns>A hashcode for this abstract file</returns>
  3302. /// <exception cref="SmbException">SmbException</exception>
  3303. public override int GetHashCode()
  3304. {
  3305. int hash;
  3306. try
  3307. {
  3308. hash = GetAddress().GetHashCode();
  3309. }
  3310. catch (UnknownHostException)
  3311. {
  3312. hash = GetServer().ToUpper().GetHashCode();
  3313. }
  3314. GetUncPath0();
  3315. return hash + _canon.ToUpper().GetHashCode();
  3316. }
  3317. protected internal virtual bool PathNamesPossiblyEqual(string path1, string path2)
  3318. {
  3319. int p1;
  3320. int p2;
  3321. int l1;
  3322. int l2;
  3323. // if unsure return this method returns true
  3324. p1 = path1.LastIndexOf('/');
  3325. p2 = path2.LastIndexOf('/');
  3326. l1 = path1.Length - p1;
  3327. l2 = path2.Length - p2;
  3328. // anything with dots voids comparison
  3329. if (l1 > 1 && path1[p1 + 1] == '.')
  3330. {
  3331. return true;
  3332. }
  3333. if (l2 > 1 && path2[p2 + 1] == '.')
  3334. {
  3335. return true;
  3336. }
  3337. return l1 == l2 && path1.RegionMatches(true, p1, path2, p2, l1);
  3338. }
  3339. /// <summary>Tests to see if two <code>SmbFile</code> objects are equal.</summary>
  3340. /// <remarks>
  3341. /// Tests to see if two <code>SmbFile</code> objects are equal. Two
  3342. /// SmbFile objects are equal when they reference the same SMB
  3343. /// resource. More specifically, two <code>SmbFile</code> objects are
  3344. /// equals if their server IP addresses are equal and the canonicalized
  3345. /// representation of their URLs, minus authentication parameters, are
  3346. /// case insensitivly and lexographically equal.
  3347. /// <p/>
  3348. /// For example, assuming the server <code>angus</code> resolves to the
  3349. /// <code>192.168.1.15</code> IP address, the below URLs would result in
  3350. /// <code>SmbFile</code>s that are equal.
  3351. /// <p><blockquote><pre>
  3352. /// smb://192.168.1.15/share/DIR/foo.txt
  3353. /// smb://angus/share/data/../dir/foo.txt
  3354. /// </pre></blockquote>
  3355. /// </remarks>
  3356. /// <param name="obj">Another <code>SmbFile</code> object to compare for equality</param>
  3357. /// <returns>
  3358. /// <code>true</code> if the two objects refer to the same SMB resource
  3359. /// and <code>false</code> otherwise
  3360. /// </returns>
  3361. /// <exception cref="SmbException">SmbException</exception>
  3362. public override bool Equals(object obj)
  3363. {
  3364. if (obj is SmbFile)
  3365. {
  3366. SmbFile f = (SmbFile)obj;
  3367. bool ret;
  3368. if (this == f)
  3369. {
  3370. return true;
  3371. }
  3372. if (PathNamesPossiblyEqual(Url.AbsolutePath, f.Url.AbsolutePath))
  3373. {
  3374. GetUncPath0();
  3375. f.GetUncPath0();
  3376. if (Runtime.EqualsIgnoreCase(_canon, f._canon))
  3377. {
  3378. try
  3379. {
  3380. ret = GetAddress().Equals(f.GetAddress());
  3381. }
  3382. catch (UnknownHostException)
  3383. {
  3384. ret = Runtime.EqualsIgnoreCase(GetServer(), f.GetServer());
  3385. }
  3386. return ret;
  3387. }
  3388. }
  3389. }
  3390. return false;
  3391. }
  3392. /// <summary>Returns the string representation of this SmbFile object.</summary>
  3393. /// <remarks>
  3394. /// Returns the string representation of this SmbFile object. This will
  3395. /// be the same as the URL used to construct this <code>SmbFile</code>.
  3396. /// This method will return the same value
  3397. /// as <code>getPath</code>.
  3398. /// </remarks>
  3399. /// <returns>The original URL representation of this SMB resource</returns>
  3400. /// <exception cref="SmbException">SmbException</exception>
  3401. public override string ToString()
  3402. {
  3403. return Url.ToString();
  3404. }
  3405. /// <summary>This URLConnection method just returns the result of <tt>length()</tt>.</summary>
  3406. /// <remarks>This URLConnection method just returns the result of <tt>length()</tt>.</remarks>
  3407. /// <returns>the length of this file or 0 if it refers to a directory</returns>
  3408. public int GetContentLength()
  3409. {
  3410. try
  3411. {
  3412. return (int)(Length() & unchecked(0xFFFFFFFFL));
  3413. }
  3414. catch (SmbException)
  3415. {
  3416. }
  3417. return 0;
  3418. }
  3419. /// <summary>This URLConnection method just returns the result of <tt>lastModified</tt>.
  3420. /// </summary>
  3421. /// <remarks>This URLConnection method just returns the result of <tt>lastModified</tt>.
  3422. /// </remarks>
  3423. /// <returns>the last modified data as milliseconds since Jan 1, 1970</returns>
  3424. public long GetDate()
  3425. {
  3426. try
  3427. {
  3428. return LastModified();
  3429. }
  3430. catch (SmbException)
  3431. {
  3432. }
  3433. return 0L;
  3434. }
  3435. /// <summary>This URLConnection method just returns the result of <tt>lastModified</tt>.
  3436. /// </summary>
  3437. /// <remarks>This URLConnection method just returns the result of <tt>lastModified</tt>.
  3438. /// </remarks>
  3439. /// <returns>the last modified data as milliseconds since Jan 1, 1970</returns>
  3440. public long GetLastModified()
  3441. {
  3442. try
  3443. {
  3444. return LastModified();
  3445. }
  3446. catch (SmbException)
  3447. {
  3448. }
  3449. return 0L;
  3450. }
  3451. /// <summary>This URLConnection method just returns a new <tt>SmbFileInputStream</tt> created with this file.
  3452. /// </summary>
  3453. /// <remarks>This URLConnection method just returns a new <tt>SmbFileInputStream</tt> created with this file.
  3454. /// </remarks>
  3455. /// <exception cref="System.IO.IOException">thrown by <tt>SmbFileInputStream</tt> constructor
  3456. /// </exception>
  3457. public InputStream GetInputStream()
  3458. {
  3459. return new SmbFileInputStream(this);
  3460. }
  3461. /// <summary>This URLConnection method just returns a new <tt>SmbFileOutputStream</tt> created with this file.
  3462. /// </summary>
  3463. /// <remarks>This URLConnection method just returns a new <tt>SmbFileOutputStream</tt> created with this file.
  3464. /// </remarks>
  3465. /// <exception cref="System.IO.IOException">thrown by <tt>SmbFileOutputStream</tt> constructor
  3466. /// </exception>
  3467. public OutputStream GetOutputStream()
  3468. {
  3469. return new SmbFileOutputStream(this);
  3470. }
  3471. /// <exception cref="System.IO.IOException"></exception>
  3472. private void ProcessAces(Ace[] aces, bool resolveSids)
  3473. {
  3474. string server = GetServerWithDfs();
  3475. int ai;
  3476. if (resolveSids)
  3477. {
  3478. Sid[] sids = new Sid[aces.Length];
  3479. string[] names = null;
  3480. for (ai = 0; ai < aces.Length; ai++)
  3481. {
  3482. sids[ai] = aces[ai].Sid;
  3483. }
  3484. for (int off = 0; off < sids.Length; off += 64)
  3485. {
  3486. int len = sids.Length - off;
  3487. if (len > 64)
  3488. {
  3489. len = 64;
  3490. }
  3491. Sid.ResolveSids(server, Auth, sids, off, len);
  3492. }
  3493. }
  3494. else
  3495. {
  3496. for (ai = 0; ai < aces.Length; ai++)
  3497. {
  3498. aces[ai].Sid.OriginServer = server;
  3499. aces[ai].Sid.OriginAuth = Auth;
  3500. }
  3501. }
  3502. }
  3503. /// <summary>
  3504. /// Return an array of Access Control Entry (ACE) objects representing
  3505. /// the security descriptor associated with this file or directory.
  3506. /// </summary>
  3507. /// <remarks>
  3508. /// Return an array of Access Control Entry (ACE) objects representing
  3509. /// the security descriptor associated with this file or directory.
  3510. /// If no DACL is present, null is returned. If the DACL is empty, an array with 0 elements is returned.
  3511. /// </remarks>
  3512. /// <param name="resolveSids">
  3513. /// Attempt to resolve the SIDs within each ACE form
  3514. /// their numeric representation to their corresponding account names.
  3515. /// </param>
  3516. /// <exception cref="System.IO.IOException"></exception>
  3517. public virtual Ace[] GetSecurity(bool resolveSids)
  3518. {
  3519. int f;
  3520. Ace[] aces;
  3521. f = Open0(ORdonly, SmbConstants.ReadControl, 0, IsDirectory() ? 1 : 0);
  3522. NtTransQuerySecurityDesc request = new NtTransQuerySecurityDesc(f, 0x04);
  3523. NtTransQuerySecurityDescResponse response = new NtTransQuerySecurityDescResponse();
  3524. try
  3525. {
  3526. Send(request, response);
  3527. }
  3528. finally
  3529. {
  3530. Close(f, 0L);
  3531. }
  3532. aces = response.SecurityDescriptor.Aces;
  3533. if (aces != null)
  3534. {
  3535. ProcessAces(aces, resolveSids);
  3536. }
  3537. return aces;
  3538. }
  3539. /// <summary>
  3540. /// Return an array of Access Control Entry (ACE) objects representing
  3541. /// the share permissions on the share exporting this file or directory.
  3542. /// </summary>
  3543. /// <remarks>
  3544. /// Return an array of Access Control Entry (ACE) objects representing
  3545. /// the share permissions on the share exporting this file or directory.
  3546. /// If no DACL is present, null is returned. If the DACL is empty, an array with 0 elements is returned.
  3547. /// <p>
  3548. /// Note that this is different from calling <tt>getSecurity</tt> on a
  3549. /// share. There are actually two different ACLs for shares - the ACL on
  3550. /// the share and the ACL on the folder being shared.
  3551. /// Go to <i>Computer Management</i>
  3552. /// &gt; <i>System Tools</i> &gt; <i>Shared Folders</i> &gt <i>Shares</i> and
  3553. /// look at the <i>Properties</i> for a share. You will see two tabs - one
  3554. /// for "Share Permissions" and another for "Security". These correspond to
  3555. /// the ACLs returned by <tt>getShareSecurity</tt> and <tt>getSecurity</tt>
  3556. /// respectively.
  3557. /// </remarks>
  3558. /// <param name="resolveSids">
  3559. /// Attempt to resolve the SIDs within each ACE form
  3560. /// their numeric representation to their corresponding account names.
  3561. /// </param>
  3562. /// <exception cref="System.IO.IOException"></exception>
  3563. public virtual Ace[] GetShareSecurity(bool resolveSids)
  3564. {
  3565. string p = Url.AbsolutePath;
  3566. MsrpcShareGetInfo rpc;
  3567. DcerpcHandle handle;
  3568. Ace[] aces;
  3569. ResolveDfs(null);
  3570. string server = GetServerWithDfs();
  3571. rpc = new MsrpcShareGetInfo(server, Tree.Share);
  3572. handle = DcerpcHandle.GetHandle("ncacn_np:" + server + "[\\PIPE\\srvsvc]", Auth);
  3573. try
  3574. {
  3575. handle.Sendrecv(rpc);
  3576. if (rpc.Retval != 0)
  3577. {
  3578. throw new SmbException(rpc.Retval, true);
  3579. }
  3580. aces = rpc.GetSecurity();
  3581. if (aces != null)
  3582. {
  3583. ProcessAces(aces, resolveSids);
  3584. }
  3585. }
  3586. finally
  3587. {
  3588. try
  3589. {
  3590. handle.Close();
  3591. }
  3592. catch (IOException ioe)
  3593. {
  3594. if (Log.Level >= 1)
  3595. {
  3596. Runtime.PrintStackTrace(ioe, Log);
  3597. }
  3598. }
  3599. }
  3600. return aces;
  3601. }
  3602. /// <summary>
  3603. /// Return an array of Access Control Entry (ACE) objects representing
  3604. /// the security descriptor associated with this file or directory.
  3605. /// </summary>
  3606. /// <remarks>
  3607. /// Return an array of Access Control Entry (ACE) objects representing
  3608. /// the security descriptor associated with this file or directory.
  3609. /// <p>
  3610. /// Initially, the SIDs within each ACE will not be resolved however when
  3611. /// <tt>getType()</tt>, <tt>getDomainName()</tt>, <tt>getAccountName()</tt>,
  3612. /// or <tt>toString()</tt> is called, the names will attempt to be
  3613. /// resolved. If the names cannot be resolved (e.g. due to temporary
  3614. /// network failure), the said methods will return default values (usually
  3615. /// <tt>S-X-Y-Z</tt> strings of fragments of).
  3616. /// <p>
  3617. /// Alternatively <tt>getSecurity(true)</tt> may be used to resolve all
  3618. /// SIDs together and detect network failures.
  3619. /// </remarks>
  3620. /// <exception cref="System.IO.IOException"></exception>
  3621. public virtual Ace[] GetSecurity()
  3622. {
  3623. return GetSecurity(false);
  3624. }
  3625. }
  3626. }