/ftplib/FtpLib/FtpConnection.cs

https://github.com/clawsoftware/clawPDF · C# · 428 lines · 373 code · 55 blank · 0 comment · 99 complexity · 33f284c89ab224a60ccd58e76a97e7cd MD5 · raw file

  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.IO;
  5. using System.Runtime.InteropServices;
  6. using System.Text;
  7. namespace clawSoft.clawPDF.ftplib.FtpLib
  8. {
  9. public class FtpConnection : IDisposable
  10. {
  11. private readonly string _password = "";
  12. private readonly string _username = "";
  13. private IntPtr _hConnect;
  14. private IntPtr _hInternet;
  15. public FtpConnection(string host)
  16. {
  17. Host = host;
  18. }
  19. public FtpConnection(string host, int port)
  20. {
  21. Host = host;
  22. Port = port;
  23. }
  24. public FtpConnection(string host, string username, string password)
  25. {
  26. Host = host;
  27. _username = username;
  28. _password = password;
  29. }
  30. public FtpConnection(string host, int port, string username, string password)
  31. {
  32. Host = host;
  33. Port = port;
  34. _username = username;
  35. _password = password;
  36. }
  37. public int Port { get; } = 21;
  38. public string Host { get; }
  39. public void Dispose()
  40. {
  41. if (_hConnect != IntPtr.Zero) WININET.InternetCloseHandle(_hConnect);
  42. if (_hInternet != IntPtr.Zero) WININET.InternetCloseHandle(_hInternet);
  43. }
  44. public void Open()
  45. {
  46. if (string.IsNullOrEmpty(Host)) throw new ArgumentNullException("Host");
  47. _hInternet = WININET.InternetOpen(Environment.UserName, 0, null, null, 4);
  48. if (_hInternet == IntPtr.Zero) Error();
  49. }
  50. public void Login()
  51. {
  52. Login(_username, _password);
  53. }
  54. public void Login(string username, string password)
  55. {
  56. if (username == null) throw new ArgumentNullException("username");
  57. if (password == null) throw new ArgumentNullException("password");
  58. _hConnect = WININET.InternetConnect(_hInternet, Host, Port, username, password, 1, 134217728, IntPtr.Zero);
  59. if (_hConnect == IntPtr.Zero) Error();
  60. }
  61. public void SetCurrentDirectory(string directory)
  62. {
  63. if (WININET.FtpSetCurrentDirectory(_hConnect, directory) == 0) Error();
  64. }
  65. public void SetLocalDirectory(string directory)
  66. {
  67. if (Directory.Exists(directory))
  68. {
  69. Environment.CurrentDirectory = directory;
  70. return;
  71. }
  72. throw new InvalidDataException($"{directory} is not a directory!");
  73. }
  74. public string GetCurrentDirectory()
  75. {
  76. var dwCurrentDirectory = 261;
  77. var stringBuilder = new StringBuilder(dwCurrentDirectory);
  78. if (WININET.FtpGetCurrentDirectory(_hConnect, stringBuilder, ref dwCurrentDirectory) == 0)
  79. {
  80. Error();
  81. return null;
  82. }
  83. return stringBuilder.ToString();
  84. }
  85. public FtpDirectoryInfo GetCurrentDirectoryInfo()
  86. {
  87. var currentDirectory = GetCurrentDirectory();
  88. return new FtpDirectoryInfo(this, currentDirectory);
  89. }
  90. public void GetFile(string remoteFile, bool failIfExists)
  91. {
  92. GetFile(remoteFile, remoteFile, failIfExists);
  93. }
  94. public void GetFile(string remoteFile, string localFile, bool failIfExists)
  95. {
  96. if (WININET.FtpGetFile(_hConnect, remoteFile, localFile, failIfExists, 128, 2, IntPtr.Zero) == 0) Error();
  97. }
  98. public void PutFile(string fileName)
  99. {
  100. PutFile(fileName, Path.GetFileName(fileName));
  101. }
  102. public void PutFile(string localFile, string remoteFile)
  103. {
  104. if (WININET.FtpPutFile(_hConnect, localFile, remoteFile, 2, IntPtr.Zero) == 0) Error();
  105. }
  106. public void RenameFile(string existingFile, string newFile)
  107. {
  108. if (WININET.FtpRenameFile(_hConnect, existingFile, newFile) == 0) Error();
  109. }
  110. public void RemoveFile(string fileName)
  111. {
  112. if (WININET.FtpDeleteFile(_hConnect, fileName) == 0) Error();
  113. }
  114. public void RemoveDirectory(string directory)
  115. {
  116. if (WININET.FtpRemoveDirectory(_hConnect, directory) == 0) Error();
  117. }
  118. [Obsolete("Use GetFiles or GetDirectories instead.")]
  119. public List<string> List()
  120. {
  121. return List(null, false);
  122. }
  123. [Obsolete("Use GetFiles or GetDirectories instead.")]
  124. public List<string> List(string mask)
  125. {
  126. return List(mask, false);
  127. }
  128. [Obsolete("Will be removed in later releases.")]
  129. private List<string> List(bool onlyDirectories)
  130. {
  131. return List(null, onlyDirectories);
  132. }
  133. [Obsolete("Will be removed in later releases.")]
  134. private List<string> List(string mask, bool onlyDirectories)
  135. {
  136. WINAPI.WIN32_FIND_DATA findFileData = default;
  137. var intPtr = WININET.FtpFindFirstFile(_hConnect, mask, ref findFileData, 67108864, IntPtr.Zero);
  138. try
  139. {
  140. var list = new List<string>();
  141. if (intPtr == IntPtr.Zero)
  142. {
  143. if (Marshal.GetLastWin32Error() == 18) return list;
  144. Error();
  145. return list;
  146. }
  147. if (onlyDirectories && (findFileData.dfFileAttributes & 0x10) == 16)
  148. {
  149. var list2 = list;
  150. var text = new string(findFileData.fileName);
  151. var trimChars = new char[1];
  152. list2.Add(text.TrimEnd(trimChars));
  153. }
  154. else if (!onlyDirectories)
  155. {
  156. var list3 = list;
  157. var text2 = new string(findFileData.fileName);
  158. var trimChars2 = new char[1];
  159. list3.Add(text2.TrimEnd(trimChars2));
  160. }
  161. findFileData = default;
  162. while (WININET.InternetFindNextFile(intPtr, ref findFileData) != 0)
  163. {
  164. if (onlyDirectories && (findFileData.dfFileAttributes & 0x10) == 16)
  165. {
  166. var list4 = list;
  167. var text3 = new string(findFileData.fileName);
  168. var trimChars3 = new char[1];
  169. list4.Add(text3.TrimEnd(trimChars3));
  170. }
  171. else if (!onlyDirectories)
  172. {
  173. var list5 = list;
  174. var text4 = new string(findFileData.fileName);
  175. var trimChars4 = new char[1];
  176. list5.Add(text4.TrimEnd(trimChars4));
  177. }
  178. findFileData = default;
  179. }
  180. if (Marshal.GetLastWin32Error() != 18) Error();
  181. return list;
  182. }
  183. finally
  184. {
  185. if (intPtr != IntPtr.Zero) WININET.InternetCloseHandle(intPtr);
  186. }
  187. }
  188. public FtpFileInfo[] GetFiles()
  189. {
  190. return GetFiles(GetCurrentDirectory());
  191. }
  192. public FtpFileInfo[] GetFiles(string mask)
  193. {
  194. var findFileData = default(WINAPI.WIN32_FIND_DATA);
  195. var intPtr = WININET.FtpFindFirstFile(_hConnect, mask, ref findFileData, 67108864, IntPtr.Zero);
  196. try
  197. {
  198. var list = new List<FtpFileInfo>();
  199. if (intPtr == IntPtr.Zero)
  200. {
  201. if (Marshal.GetLastWin32Error() == 18) return list.ToArray();
  202. Error();
  203. return list.ToArray();
  204. }
  205. if ((findFileData.dfFileAttributes & 0x10) != 16)
  206. {
  207. var text = new string(findFileData.fileName);
  208. var trimChars = new char[1];
  209. var ftpFileInfo = new FtpFileInfo(this, text.TrimEnd(trimChars));
  210. ftpFileInfo.LastAccessTime = findFileData.ftLastAccessTime.ToDateTime();
  211. ftpFileInfo.LastWriteTime = findFileData.ftLastWriteTime.ToDateTime();
  212. ftpFileInfo.CreationTime = findFileData.ftCreationTime.ToDateTime();
  213. ftpFileInfo.Attributes = (FileAttributes)findFileData.dfFileAttributes;
  214. list.Add(ftpFileInfo);
  215. }
  216. findFileData = default;
  217. while (WININET.InternetFindNextFile(intPtr, ref findFileData) != 0)
  218. {
  219. if ((findFileData.dfFileAttributes & 0x10) != 16)
  220. {
  221. var text2 = new string(findFileData.fileName);
  222. var trimChars2 = new char[1];
  223. var ftpFileInfo2 = new FtpFileInfo(this, text2.TrimEnd(trimChars2));
  224. ftpFileInfo2.LastAccessTime = findFileData.ftLastAccessTime.ToDateTime();
  225. ftpFileInfo2.LastWriteTime = findFileData.ftLastWriteTime.ToDateTime();
  226. ftpFileInfo2.CreationTime = findFileData.ftCreationTime.ToDateTime();
  227. ftpFileInfo2.Attributes = (FileAttributes)findFileData.dfFileAttributes;
  228. list.Add(ftpFileInfo2);
  229. }
  230. findFileData = default;
  231. }
  232. if (Marshal.GetLastWin32Error() != 18) Error();
  233. return list.ToArray();
  234. }
  235. finally
  236. {
  237. if (intPtr != IntPtr.Zero) WININET.InternetCloseHandle(intPtr);
  238. }
  239. }
  240. public FtpDirectoryInfo[] GetDirectories()
  241. {
  242. return GetDirectories(GetCurrentDirectory());
  243. }
  244. public FtpDirectoryInfo[] GetDirectories(string path)
  245. {
  246. var findFileData = default(WINAPI.WIN32_FIND_DATA);
  247. var intPtr = WININET.FtpFindFirstFile(_hConnect, path, ref findFileData, 67108864, IntPtr.Zero);
  248. try
  249. {
  250. var list = new List<FtpDirectoryInfo>();
  251. if (intPtr == IntPtr.Zero)
  252. {
  253. if (Marshal.GetLastWin32Error() == 18) return list.ToArray();
  254. Error();
  255. return list.ToArray();
  256. }
  257. if ((findFileData.dfFileAttributes & 0x10) == 16)
  258. {
  259. var text = new string(findFileData.fileName);
  260. var trimChars = new char[1];
  261. var ftpDirectoryInfo = new FtpDirectoryInfo(this, text.TrimEnd(trimChars));
  262. ftpDirectoryInfo.LastAccessTime = findFileData.ftLastAccessTime.ToDateTime();
  263. ftpDirectoryInfo.LastWriteTime = findFileData.ftLastWriteTime.ToDateTime();
  264. ftpDirectoryInfo.CreationTime = findFileData.ftCreationTime.ToDateTime();
  265. ftpDirectoryInfo.Attributes = (FileAttributes)findFileData.dfFileAttributes;
  266. list.Add(ftpDirectoryInfo);
  267. }
  268. findFileData = default;
  269. while (WININET.InternetFindNextFile(intPtr, ref findFileData) != 0)
  270. {
  271. if ((findFileData.dfFileAttributes & 0x10) == 16)
  272. {
  273. var text2 = new string(findFileData.fileName);
  274. var trimChars2 = new char[1];
  275. var ftpDirectoryInfo2 = new FtpDirectoryInfo(this, text2.TrimEnd(trimChars2));
  276. ftpDirectoryInfo2.LastAccessTime = findFileData.ftLastAccessTime.ToDateTime();
  277. ftpDirectoryInfo2.LastWriteTime = findFileData.ftLastWriteTime.ToDateTime();
  278. ftpDirectoryInfo2.CreationTime = findFileData.ftCreationTime.ToDateTime();
  279. ftpDirectoryInfo2.Attributes = (FileAttributes)findFileData.dfFileAttributes;
  280. list.Add(ftpDirectoryInfo2);
  281. }
  282. findFileData = default;
  283. }
  284. if (Marshal.GetLastWin32Error() != 18) Error();
  285. return list.ToArray();
  286. }
  287. finally
  288. {
  289. if (intPtr != IntPtr.Zero) WININET.InternetCloseHandle(intPtr);
  290. }
  291. }
  292. public void CreateDirectory(string path)
  293. {
  294. if (WININET.FtpCreateDirectory(_hConnect, path) == 0) Error();
  295. }
  296. public bool DirectoryExists(string path)
  297. {
  298. var findFileData = default(WINAPI.WIN32_FIND_DATA);
  299. var intPtr = WININET.FtpFindFirstFile(_hConnect, path, ref findFileData, 67108864, IntPtr.Zero);
  300. try
  301. {
  302. if (intPtr == IntPtr.Zero) return false;
  303. return true;
  304. }
  305. finally
  306. {
  307. if (intPtr != IntPtr.Zero) WININET.InternetCloseHandle(intPtr);
  308. }
  309. }
  310. public bool FileExists(string path)
  311. {
  312. var findFileData = default(WINAPI.WIN32_FIND_DATA);
  313. var intPtr = WININET.FtpFindFirstFile(_hConnect, path, ref findFileData, 67108864, IntPtr.Zero);
  314. try
  315. {
  316. if (intPtr == IntPtr.Zero) return false;
  317. return true;
  318. }
  319. finally
  320. {
  321. if (intPtr != IntPtr.Zero) WININET.InternetCloseHandle(intPtr);
  322. }
  323. }
  324. public string SendCommand(string cmd)
  325. {
  326. var ftpCommand = default(IntPtr);
  327. string a;
  328. var num = (a = cmd) == null || !(a == "PASV")
  329. ? WININET.FtpCommand(_hConnect, false, 1, cmd, IntPtr.Zero, ref ftpCommand)
  330. : WININET.FtpCommand(_hConnect, false, 1, cmd, IntPtr.Zero, ref ftpCommand);
  331. var num2 = 8192;
  332. if (num == 0)
  333. {
  334. Error();
  335. }
  336. else if (ftpCommand != IntPtr.Zero)
  337. {
  338. var stringBuilder = new StringBuilder(num2);
  339. var bytesRead = 0;
  340. do
  341. {
  342. num = WININET.InternetReadFile(ftpCommand, stringBuilder, num2, ref bytesRead);
  343. } while (num == 1 && bytesRead > 1);
  344. return stringBuilder.ToString();
  345. }
  346. return "";
  347. }
  348. public void Close()
  349. {
  350. WININET.InternetCloseHandle(_hConnect);
  351. _hConnect = IntPtr.Zero;
  352. WININET.InternetCloseHandle(_hInternet);
  353. _hInternet = IntPtr.Zero;
  354. }
  355. private string InternetLastResponseInfo(ref int code)
  356. {
  357. var bufferLength = 8192;
  358. var stringBuilder = new StringBuilder(bufferLength);
  359. WININET.InternetGetLastResponseInfo(ref code, stringBuilder, ref bufferLength);
  360. return stringBuilder.ToString();
  361. }
  362. private void Error()
  363. {
  364. var code = Marshal.GetLastWin32Error();
  365. if (code == 12003)
  366. {
  367. var message = InternetLastResponseInfo(ref code);
  368. throw new FtpException(code, message);
  369. }
  370. throw new Win32Exception(code);
  371. }
  372. }
  373. }