<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>libmtp &amp;mdash; Gerrit Niezen</title>
    <link>https://gerritniezen.com/tag:libmtp</link>
    <description>Maker of open-source software and hardware.</description>
    <pubDate>Thu, 30 Apr 2026 05:58:51 +0000</pubDate>
    <image>
      <url>https://i.snap.as/aMPXpIot.png</url>
      <title>libmtp &amp;mdash; Gerrit Niezen</title>
      <link>https://gerritniezen.com/tag:libmtp</link>
    </image>
    <item>
      <title>Getting a Node.js library using libmtp working on Windows</title>
      <link>https://gerritniezen.com/getting-a-node-js-library-using-libmtp-working-on-windows?pk_campaign=rss-feed</link>
      <description>&lt;![CDATA[This is a follow-on to Part 1 and Part 2 of my adventures in connecting to Android devices over MTP using Node.js, on Windows.&#xA;&#xA;While compiling the Node.js native module, I got the following error:&#xA;&#xA;Macro definition of snprintf conflicts with Standard Library function declaration&#xA;&#xA;Searching StackOverflow led to this solution, which I added to the libmtp source code:&#xA;&#xA;if MSCVER &lt; 1900&#xA;define snprintf snprintf&#xA;endif&#xA;&#xA;I also kept on getting a &#34;Module not found&#34; error, until I re-read my own post and used Dependency Walker to figure out that for some reason my .node file is looking for libmtp-9.dll.dll instead of libmtp-9.dll. 🤷‍♂️️ I also had to copy libusb-1.0.dll into the same folder, as it was looking for that too.&#xA;&#xA;Finally, like magic, I was able to connect to a device on Windows over MTP with my own Node.js library using libmtp, instead of the Windows MTP implementation that can only be accessed through Windows Explorer or the Windows APIs.&#xA;&#xA;And I just submitted a PR to get Windows builds fixed in the upstream libmtp library.&#xA;&#xA;Next step: Getting it compiled for 32-bit Windows using i686-w64-mingw32 and/or i686-mingw32&#xA;&#xA;---&#xA;I’m publishing this as part of 100 Days To Offload. You can join in yourself by visiting https://100daystooffload.com.&#xA;&#xA;#100DaysToOffload #day34 #libmtp #Node.js&#xA;&#xA;iComment on this post/i&#xD;&#xA;div id=&#34;cusdisthread&#34;/div]]&gt;</description>
      <content:encoded><![CDATA[<p>This is a follow-on to <a href="https://gerritniezen.com/attempting-to-get-libmtp-compiled-on-windows">Part 1</a> and <a href="https://gerritniezen.com/more-adventures-with-libmtp">Part 2</a> of my adventures in connecting to Android devices over MTP using Node.js, on Windows.</p>

<p>While compiling the Node.js native module, I got the following error:</p>

<pre><code>Macro definition of snprintf conflicts with Standard Library function declaration
</code></pre>

<p><a href="https://stackoverflow.com/questions/51897245/visual-studio-macro-definition-of-snprintf-conflict">Searching StackOverflow</a> led to this solution, which I added to the libmtp source code:</p>

<pre><code class="language-c">#if _MSC_VER &lt; 1900
#define snprintf _snprintf
#endif
</code></pre>

<p>I also kept on getting a “Module not found” error, until I re-read <a href="https://gerritniezen.com/using-libavutils-lzo-algorithm-in-node-js-part-5">my own post</a> and used Dependency Walker to figure out that for some reason my <code>.node</code> file is looking for <code>libmtp-9.dll.dll</code> instead of <code>libmtp-9.dll</code>. 🤷‍♂️️ I also had to copy <code>libusb-1.0.dll</code> into the same folder, as it was looking for that too.</p>

<p>Finally, like magic, I was able to connect to a device on Windows over MTP with my own Node.js library using libmtp, instead of the Windows MTP implementation that can only be accessed through Windows Explorer or the Windows APIs.</p>

<p>And I just submitted <a href="https://github.com/libmtp/libmtp/pull/41">a PR to get Windows builds fixed in the upstream libmtp library</a>.</p>

<p>Next step: Getting it compiled for 32-bit Windows using <code>i686-w64-mingw32</code> and/or <code>i686-mingw32</code></p>

<hr/>

<p>I’m publishing this as part of 100 Days To Offload. You can join in yourself by visiting <a href="https://100daystooffload.com">https://100daystooffload.com</a>.</p>

<p><a href="https://gerritniezen.com/tag:100DaysToOffload" class="hashtag"><span>#</span><span class="p-category">100DaysToOffload</span></a> <a href="https://gerritniezen.com/tag:day34" class="hashtag"><span>#</span><span class="p-category">day34</span></a> <a href="https://gerritniezen.com/tag:libmtp" class="hashtag"><span>#</span><span class="p-category">libmtp</span></a> <a href="https://gerritniezen.com/tag:Node" class="hashtag"><span>#</span><span class="p-category">Node</span></a>.js</p>

<p><i>Comment on this post</i>
<div id="cusdis_thread" id="cusdis_thread"></div></p>
]]></content:encoded>
      <guid>https://gerritniezen.com/getting-a-node-js-library-using-libmtp-working-on-windows</guid>
      <pubDate>Fri, 29 May 2020 15:17:11 +0000</pubDate>
    </item>
    <item>
      <title>More adventures with libmtp</title>
      <link>https://gerritniezen.com/more-adventures-with-libmtp?pk_campaign=rss-feed</link>
      <description>&lt;![CDATA[So even though I managed to get libmtp compiled under Windows, I can&#39;t get it to work with Node.js. I&#39;ve decided to take the same approach as what I did with ffmpeg&#39;s libavutil library, and cross-compile it under Linux instead.&#xA;&#xA;To do this, I needed mingw64 on my Linux machine:&#xA;&#xA;sudo apt-get install mingw-w64&#xA;sudo apt-get install mingw-w64-tools&#xA;&#xA;It doesn&#39;t look like libusb has been pre-compiled for mingw64 on Linux, so I had to do the following:&#xA;&#xA;git clone https://github.com/libusb/libusb.git&#xA; git checkout v1.0.23&#xA;./autogen.sh&#xA;./configure --host=x8664-w64-mingw32&#xA;make&#xA;DESTDIR=$HOME/Code/mingw64/ make install&#xA;&#xA;This installs the libusb library (compiled for Windows) under $HOME/Code/mingw64/. Then I had to configure libmtp to use our Windows libusb build:&#xA;&#xA;PKGCONFIGPATH=$HOME/Code/mingw64/usr/local/lib/pkgconfig  ./configure --host=x8664-w64-mingw32&#xA;make&#xA;&#xA;Again I had to fix unicode.c to get it working. I should submit this work as  a PR to libmtp.&#xA;&#xA;Next step: Try to get this working in as a native Node.js addon.&#xA;&#xA;For reference:&#xA;http://www.tinc-vpn.org/examples/cross-compiling-64-bit-windows-binary/&#xA;&#xA;---&#xA;I’m publishing this as part of 100 Days To Offload. You can join in yourself by visiting https://100daystooffload.com.&#xA;&#xA;#100DaysToOffload #day33 #libmtp&#xA;&#xA;iComment on this post/i&#xD;&#xA;div id=&#34;cusdis_thread&#34;/div]]&gt;</description>
      <content:encoded><![CDATA[<p>So even though I managed to <a href="https://gerritniezen.com/attempting-to-get-libmtp-compiled-on-windows">get libmtp compiled under Windows</a>, I can&#39;t get it to work with Node.js. I&#39;ve decided to take the same approach as what I did with ffmpeg&#39;s libavutil library, and <a href="https://gerritniezen.com/using-libavutils-lzo-algorithm-in-node-js-part-5">cross-compile it under Linux</a> instead.</p>

<p>To do this, I needed mingw64 on my Linux machine:</p>

<pre><code class="language-sh">sudo apt-get install mingw-w64
sudo apt-get install mingw-w64-tools
</code></pre>

<p>It doesn&#39;t look like libusb has been pre-compiled for mingw64 on Linux, so I had to do the following:</p>

<pre><code class="language-sh">git clone https://github.com/libusb/libusb.git
 git checkout v1.0.23
./autogen.sh
./configure --host=x86_64-w64-mingw32
make
DESTDIR=$HOME/Code/mingw64/ make install
</code></pre>

<p>This installs the libusb library (compiled for Windows) under <code>$HOME/Code/mingw64/</code>. Then I had to configure libmtp to use our Windows libusb build:</p>

<pre><code class="language-sh">PKG_CONFIG_PATH=$HOME/Code/mingw64/usr/local/lib/pkgconfig  ./configure --host=x86_64-w64-mingw32
make
</code></pre>

<p>Again I had to fix <code>unicode.c</code> to get it working. I should submit <a href="https://gerritniezen.com/attempting-to-get-libmtp-compiled-on-windows">this work</a> as  a PR to libmtp.</p>

<p>Next step: Try to get this working in as a native Node.js addon.</p>

<p>For reference:
<a href="http://www.tinc-vpn.org/examples/cross-compiling-64-bit-windows-binary/">http://www.tinc-vpn.org/examples/cross-compiling-64-bit-windows-binary/</a></p>

<hr/>

<p>I’m publishing this as part of 100 Days To Offload. You can join in yourself by visiting <a href="https://100daystooffload.com">https://100daystooffload.com</a>.</p>

<p><a href="https://gerritniezen.com/tag:100DaysToOffload" class="hashtag"><span>#</span><span class="p-category">100DaysToOffload</span></a> <a href="https://gerritniezen.com/tag:day33" class="hashtag"><span>#</span><span class="p-category">day33</span></a> <a href="https://gerritniezen.com/tag:libmtp" class="hashtag"><span>#</span><span class="p-category">libmtp</span></a></p>

<p><i>Comment on this post</i>
<div id="cusdis_thread" id="cusdis_thread"></div></p>
]]></content:encoded>
      <guid>https://gerritniezen.com/more-adventures-with-libmtp</guid>
      <pubDate>Thu, 28 May 2020 15:23:01 +0000</pubDate>
    </item>
    <item>
      <title>Attempting to get libmtp compiled on Windows</title>
      <link>https://gerritniezen.com/attempting-to-get-libmtp-compiled-on-windows?pk_campaign=rss-feed</link>
      <description>&lt;![CDATA[A couple of days ago I mentioned that I&#39;m attempting to compile libmtp under MSYS2/MINGW64. Steps so far:&#xA;&#xA;Install MSYS2&#xA;Do pacman -Syuu repeatedly after first start until everything is up to date&#xA;Install git: pacman -S git&#xA;Install base-devel for basic development utilities&#xA;install mingw-w64-x8664-toolchain (as we need   mingw-w64-x8664-gcc to not get spawnv errors, see https://github.com/libimobiledevice/libplist/issues/136)&#xA;Install mingw-w64-x8664-libiconv&#xA;Install mingw-w64-x8664-libusb&#xA;Remember to run autogen.sh before running ./configure&#xA;Run make&#xA;&#xA;Some useful MSYS2-specific things:&#xA;&#xA;Use cd /c/ to get to the C: drive&#xA;pacman -S to install, -R to remove and -Ss to search&#xA;To access Windows path (e.g. to run node/npm, which can&#39;t be installed in MSYS2), add -use-full-path to the mingw64 app shortcut, or set environment variable MSYS2PATHTYPE to inherit&#xA;&#xA;Now, after all of this I still got the following error:&#xA;&#xA;unicode.c: In function &#39;utf16toutf8&#39;:&#xA;unicode.c:91:23: error: &#39;PTPParams&#39; {aka &#39;struct PTPParams&#39;} has no member named &#39;cducs2tolocale&#39;&#xA;   91 |   nconv = iconv(params-  cducs2tolocale, &amp;stringp, &amp;convlen, &amp;locp, &amp;convmax);&#xA;      |                       ^~&#xA;unicode.c: In function &#39;utf8toutf16&#39;:&#xA;unicode.c:126:23: error: &#39;PTPParams&#39; {aka &#39;struct PTPParams&#39;} has no member named &#39;cdlocaletoucs2&#39;&#xA;  126 |   nconv = iconv(params-  cdlocaletoucs2, &amp;stringp, &amp;convlen, &amp;unip, &amp;convmax);&#xA;&#xA;Turns out, it&#39;s a known issue. Based on a potential fix linked to in that GitHub issue, I was able to write a fix for a different file:&#xA;&#xA;diff --git a/src/unicode.c b/src/unicode.c&#xA;index 2adc94e..b14274b 100644&#xA;--- a/src/unicode.c&#xA;+++ b/src/unicode.c&#xA;@@ -87,12 +87,14 @@ char utf16toutf8(LIBMTPmtpdevicet device, const uint16t unicstr)&#xA;   sizet convmax = STRINGBUFFERLENGTH3;&#xA;&#xA;   loclstr[0]=&#39;\0&#39;;&#xA;if defined(HAVEICONV) &amp;&amp; defined(HAVELANGINFOH)&#xA;   / Do the conversion.  /&#xA;   nconv = iconv(params-  cducs2tolocale, &amp;stringp, &amp;convlen, &amp;locp, &amp;convmax);&#xA;   if (nconv == (sizet) -1) {&#xA;     // Return partial string anyway.&#xA;     locp = &#39;\0&#39;;&#xA;   }&#xA;endif&#xA;   loclstr[STRINGBUFFERLENGTH3] = &#39;\0&#39;;&#xA;   // Strip off any BOM, it&#39;s totally useless...&#xA;   if ((uint8t) loclstr[0] == 0xEFU &amp;&amp; (uint8t) loclstr[1] == 0xBBU &amp;&amp; (uint8t) loclstr[2] == 0xBFU) {&#xA;@@ -121,7 +123,7 @@ uint16t utf8toutf16(LIBMTPmtpdevicet device, const char localstr)&#xA;&#xA;   unicstr[0]=&#39;\0&#39;;&#xA;   unicstr[1]=&#39;\0&#39;;&#xA;if defined(HAVEICONV) &amp;&amp; defined(HAVELANGINFOH)&#xA;   / Do the conversion.  /&#xA;   nconv = iconv(params-  cdlocaletoucs2, &amp;stringp, &amp;convlen, &amp;unip, &amp;convmax);&#xA;&#xA;@@ -130,6 +132,7 @@ uint16t utf8toutf16(LIBMTPmtpdevicet device, const char localstr)&#xA;     unip[0] = &#39;\0&#39;;&#xA;     unip[1] = &#39;\0&#39;;&#xA;   }&#xA;endif&#xA;   // make sure the string is null terminated&#xA;   unicstr[STRINGBUFFERLENGTH2] = &#39;\0&#39;;&#xA;   unicstr[STRINGBUFFERLENGTH2+1] = &#39;\0&#39;;&#xA;&#xA;Lo and behold, I got it to compile!&#xA;&#xA;---&#xA;I’m publishing this as part of 100 Days To Offload. You can join in yourself by visiting https://100daystooffload.com.&#xA;&#xA;#100DaysToOffload #day26 #libmtp&#xA;&#xA;iComment on this post/i&#xD;&#xA;div id=&#34;cusdisthread&#34;/div]]&gt;</description>
      <content:encoded><![CDATA[<p><a href="https://gerritniezen.com/a-cross-platform-approach-to-accessing-android-devices-over-usb">A couple of days ago</a> I mentioned that I&#39;m attempting to compile <code>libmtp</code> under MSYS2/MINGW64. Steps so far:</p>
<ul><li>Install <a href="https://www.msys2.org/">MSYS2</a></li>
<li>Do <code>pacman -Syuu</code> repeatedly after first start until everything is up to date</li>
<li>Install git: <code>pacman -S git</code></li>
<li>Install <code>base-devel</code> for basic development utilities</li>
<li>install <code>mingw-w64-x86_64-toolchain</code> (as we need   <code>mingw-w64-x86_64-gcc</code> to not get <code>_spawnv</code> errors, see <a href="https://github.com/libimobiledevice/libplist/issues/136">https://github.com/libimobiledevice/libplist/issues/136</a>)</li>
<li>Install <code>mingw-w64-x86_64-libiconv</code></li>
<li>Install <code>mingw-w64-x86_64-libusb</code></li>
<li>Remember to run <code>autogen.sh</code> before running <code>./configure</code></li>
<li>Run <code>make</code></li></ul>

<p>Some useful MSYS2-specific things:</p>
<ul><li>Use <code>cd /c/</code> to get to the C: drive</li>
<li><code>pacman -S</code> to install, <code>-R</code> to remove and <code>-Ss</code> to search</li>
<li>To access Windows path (e.g. to run node/npm, which can&#39;t be installed in MSYS2), add <code>-use-full-path</code> to the mingw64 app shortcut, or set environment variable <code>MSYS2_PATH_TYPE</code> to <code>inherit</code></li></ul>

<p>Now, after all of this I still got the following error:</p>

<pre><code>unicode.c: In function &#39;utf16_to_utf8&#39;:
unicode.c:91:23: error: &#39;PTPParams&#39; {aka &#39;struct _PTPParams&#39;} has no member named &#39;cd_ucs2_to_locale&#39;
   91 |   nconv = iconv(params-&gt;cd_ucs2_to_locale, &amp;stringp, &amp;convlen, &amp;locp, &amp;convmax);
      |                       ^~
unicode.c: In function &#39;utf8_to_utf16&#39;:
unicode.c:126:23: error: &#39;PTPParams&#39; {aka &#39;struct _PTPParams&#39;} has no member named &#39;cd_locale_to_ucs2&#39;
  126 |   nconv = iconv(params-&gt;cd_locale_to_ucs2, &amp;stringp, &amp;convlen, &amp;unip, &amp;convmax);
</code></pre>

<p>Turns out, <a href="https://github.com/libmtp/libmtp/issues/20">it&#39;s a known issue</a>. Based on a potential fix linked to in that GitHub issue, I was able to write a fix for a different file:</p>

<pre><code>diff --git a/src/unicode.c b/src/unicode.c
index 2adc94e..b14274b 100644
--- a/src/unicode.c
+++ b/src/unicode.c
@@ -87,12 +87,14 @@ char *utf16_to_utf8(LIBMTP_mtpdevice_t *device, const uint16_t *unicstr)
   size_t convmax = STRING_BUFFER_LENGTH*3;

   loclstr[0]=&#39;\0&#39;;
+  #if defined(HAVE_ICONV) &amp;&amp; defined(HAVE_LANGINFO_H)
   /* Do the conversion.  */
   nconv = iconv(params-&gt;cd_ucs2_to_locale, &amp;stringp, &amp;convlen, &amp;locp, &amp;convmax);
   if (nconv == (size_t) -1) {
     // Return partial string anyway.
     *locp = &#39;\0&#39;;
   }
+  #endif
   loclstr[STRING_BUFFER_LENGTH*3] = &#39;\0&#39;;
   // Strip off any BOM, it&#39;s totally useless...
   if ((uint8_t) loclstr[0] == 0xEFU &amp;&amp; (uint8_t) loclstr[1] == 0xBBU &amp;&amp; (uint8_t) loclstr[2] == 0xBFU) {
@@ -121,7 +123,7 @@ uint16_t *utf8_to_utf16(LIBMTP_mtpdevice_t *device, const char *localstr)

   unicstr[0]=&#39;\0&#39;;
   unicstr[1]=&#39;\0&#39;;
-
+  #if defined(HAVE_ICONV) &amp;&amp; defined(HAVE_LANGINFO_H)
   /* Do the conversion.  */
   nconv = iconv(params-&gt;cd_locale_to_ucs2, &amp;stringp, &amp;convlen, &amp;unip, &amp;convmax);

@@ -130,6 +132,7 @@ uint16_t *utf8_to_utf16(LIBMTP_mtpdevice_t *device, const char *localstr)
     unip[0] = &#39;\0&#39;;
     unip[1] = &#39;\0&#39;;
   }
+  #endif
   // make sure the string is null terminated
   unicstr[STRING_BUFFER_LENGTH*2] = &#39;\0&#39;;
   unicstr[STRING_BUFFER_LENGTH*2+1] = &#39;\0&#39;;
</code></pre>

<p>Lo and behold, I got it to compile!</p>

<hr/>

<p>I’m publishing this as part of 100 Days To Offload. You can join in yourself by visiting <a href="https://100daystooffload.com">https://100daystooffload.com</a>.</p>

<p><a href="https://gerritniezen.com/tag:100DaysToOffload" class="hashtag"><span>#</span><span class="p-category">100DaysToOffload</span></a> <a href="https://gerritniezen.com/tag:day26" class="hashtag"><span>#</span><span class="p-category">day26</span></a> <a href="https://gerritniezen.com/tag:libmtp" class="hashtag"><span>#</span><span class="p-category">libmtp</span></a></p>

<p><i>Comment on this post</i>
<div id="cusdis_thread" id="cusdis_thread"></div></p>
]]></content:encoded>
      <guid>https://gerritniezen.com/attempting-to-get-libmtp-compiled-on-windows</guid>
      <pubDate>Thu, 21 May 2020 15:46:22 +0000</pubDate>
    </item>
  </channel>
</rss>